static void sendhelpfile(struct Client *source_p, const char *path, const char *topic, const char *nick) { FBFILE *file; char line[HELPLEN]; if((file = fbopen(path, "r")) == NULL) { sendto_one(source_p, form_str(ERR_HELPNOTFOUND), me.name, nick, topic); return; } if(fbgets(line, sizeof(line), file) == NULL) { sendto_one(source_p, form_str(ERR_HELPNOTFOUND), me.name, nick, topic); return; } sendto_one(source_p, form_str(RPL_HELPSTART), me.name, nick, topic, line); while (fbgets(line, sizeof(line), file)) { sendto_one(source_p, form_str(RPL_HELPTXT), me.name, nick, topic, line); } fbclose(file); sendto_one(source_p, form_str(RPL_ENDOFHELP), me.name, nick, topic); return; }
static void sendhelpfile(struct Client *source_p, const char *path, const char *topic) { FBFILE *file; char line[HELPLEN]; char started = 0; int type; if ((file = fbopen(path, "r")) == NULL) { sendto_one(source_p, form_str(ERR_HELPNOTFOUND), me.name, source_p->name, topic); return; } if (fbgets(line, sizeof(line), file) == NULL) { sendto_one(source_p, form_str(ERR_HELPNOTFOUND), me.name, source_p->name, topic); return; } else if (line[0] != '#') { line[strlen(line) - 1] = '\0'; sendto_one(source_p, form_str(RPL_HELPSTART), me.name, source_p->name, topic, line); started = 1; } while (fbgets(line, sizeof(line), file)) { line[strlen(line) - 1] = '\0'; if (line[0] != '#') { if (!started) { type = RPL_HELPSTART; started = 1; } else type = RPL_HELPTXT; sendto_one(source_p, form_str(RPL_HELPTXT), me.name, source_p->name, topic, line); } } fbclose(file); sendto_one(source_p, form_str(RPL_HELPTXT), me.name, source_p->name, topic, ""); sendto_one(source_p, form_str(RPL_ENDOFHELP), me.name, source_p->name, topic); }
void parse_k_file(FBFILE *file) { struct ConfItem *aconf; char* user_field=(char *)NULL; char* reason_field=(char *)NULL; char* host_field=(char *)NULL; char line[BUFSIZE]; char* p; while (fbgets(line, sizeof(line), file)) { if ((p = strchr(line, '\n')) != NULL) *p = '\0'; if ((*line == '\0') || (*line == '#')) continue; if ((user_field = getfield(line)) == NULL) continue; if ((host_field = getfield(NULL)) == NULL) continue; if ((reason_field = getfield(NULL)) == NULL) continue; aconf = make_conf(); aconf->status = CONF_KILL; conf_add_fields(aconf,host_field,reason_field,user_field,0,NULL); if (aconf->host != NULL) add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf); } }
void parse_d_file(FBFILE *file) { struct ConfItem *aconf; char* reason_field=(char *)NULL; char* host_field=(char *)NULL; char line[BUFSIZE]; char* p; while (fbgets(line, sizeof(line), file)) { if ((p = strchr(line, '\n'))) *p = '\0'; if ((*line == '\0') || (line[0] == '#')) continue; if ((host_field = getfield(line)) == NULL) continue; if ((reason_field = getfield(NULL)) == NULL) continue; aconf = make_conf(); aconf->status = CONF_DLINE; conf_add_fields(aconf,host_field,reason_field,"",0,NULL); conf_add_d_conf(aconf); } }
/** Tell a user that they are banned, dumping the message from a file. * @param sptr Client being rejected * @param filename Send this file's contents to \a sptr */ static void killcomment(struct Client* sptr, const char* filename) { FBFILE* file = 0; char line[80]; struct stat sb; if (NULL == (file = fbopen(filename, "r"))) { send_reply(sptr, ERR_NOMOTD); send_reply(sptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":Connection from your host is refused on this server."); return; } fbstat(&sb, file); while (fbgets(line, sizeof(line) - 1, file)) { char* end = line + strlen(line); while (end > line) { --end; if ('\n' == *end || '\r' == *end) *end = '\0'; else break; } send_reply(sptr, RPL_MOTD, line); } send_reply(sptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":Connection from your host is refused on this server."); fbclose(file); }
void parse_resv_file(FBFILE *file) { char *reason_field; char *host_field; char line[BUFSIZE]; char *p; while(fbgets(line, sizeof(line), file)) { if((p = strchr(line, '\n'))) *p = '\0'; if((*line == '\0') || (line[0] == '#')) continue; if((host_field = getfield(line)) == NULL) continue; if((reason_field = getfield(NULL)) == NULL) continue; if(IsChannelName(host_field)) create_resv(host_field, reason_field, RESV_CHANNEL); else if(clean_resv_nick(host_field)) create_resv(host_field, reason_field, RESV_NICK); } }
/* check_pidfile() * * inputs - filename+path of pid file * output - none * side effects - reads pid from pidfile and checks if ircd is in process * list. if it is, gracefully exits * -kre */ static void check_pidfile (const char *filename) { FBFILE *fb; char buff[32]; pid_t pidfromfile; /* Don't do logging here, since we don't have log() initialised */ if ((fb = fbopen (filename, "r"))) { if (fbgets (buff, 20, fb) == NULL) { /* log(L_ERROR, "Error reading from pid file %s (%s)", filename, * strerror(errno)); */ } else { pidfromfile = atoi (buff); if (!kill (pidfromfile, 0)) { /* log(L_ERROR, "Server is already running"); */ printf ("ircd: daemon is already running\n"); exit (-1); } } fbclose (fb); } else if (errno != ENOENT) { /* log(L_ERROR, "Error opening pid file %s", filename); */ } }
/* parse_resvconf() * * inputs - NONE * output - -1 if failure 0 if success * side effects - fills in irc_nsaddr_list */ static int parse_resvconf(void) { char *p; char *opt; char *arg; char input[MAXLINE]; FBFILE *file; /* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps * for cygwin support etc. this hardcodes it to unix for now -db */ if ((file = fbopen("/etc/resolv.conf", "r")) == NULL) return(-1); while (fbgets(input, MAXLINE, file) != NULL) { /* blow away any newline */ if ((p = strpbrk(input, "\r\n")) != NULL) *p = '\0'; /* Ignore comment lines immediately */ if (*input == '#') continue; p = input; /* skip until something thats not a space is seen */ while (IsSpace(*p)) p++; /* if at this point, have a '\0' then continue */ if (*p == '\0') continue; /* skip until a space is found */ opt = input; while (!IsSpace(*p)) if (*p++ == '\0') continue; /* no arguments?.. ignore this line */ /* blow away the space character */ *p++ = '\0'; /* skip these spaces that are before the argument */ while (IsSpace(*p)) p++; /* Now arg should be right where p is pointing */ arg = p; if ((p = strpbrk(arg, " \t")) != NULL) *p = '\0'; /* take the first word */ if (strcasecmp(opt, "domain") == 0) strlcpy(irc_domain, arg, HOSTLEN); else if (strcasecmp(opt, "nameserver") == 0) add_nameserver(arg); } fbclose(file); return(0); }
void parse_x_file(FBFILE * file) { struct ConfItem *aconf; char *reason_field = NULL; char *host_field = NULL; char *port_field = NULL; char line[BUFSIZE]; char *p; while (fbgets(line, sizeof(line), file)) { if((p = strchr(line, '\n'))) *p = '\0'; if((*line == '\0') || (line[0] == '#')) continue; host_field = getfield(line); if(BadPtr(host_field)) continue; port_field = getfield(NULL); if(BadPtr(port_field)) continue; reason_field = getfield(NULL); if(BadPtr(reason_field)) continue; aconf = make_conf(); aconf->status = CONF_XLINE; conf_add_fields(aconf, host_field, reason_field, "", port_field, NULL); conf_add_x_conf(aconf); } }
/* Now, our job is a bit harder. I will scan through the SPOOF_FILE * and read all auths{} (assuming they are written in our line formatting..), * then rewrite them skipping the one to delete. --adx */ static void mo_delspoof(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { #ifdef SPOOF_FILE FBFILE *f, *fout; int ignore_it = 1, spoof_found = 0; char buffer[1024], *tmp; #endif const char *user = NULL; char *host = NULL; if (MyConnect(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, parv[0], "DELSPOOF"); return; } if (parv[1] == NULL || !*parv[1]) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Syntax: /DELSPOOF <user@host>", me.name, source_p->name); return; } /* check user@host mask */ (void) collapse(parv[1]); host = strchr(parv[1], '@'); if (host != NULL) { user = parv[1]; *host = '\0'; host++; } else { user = "******"; host = parv[1]; } #ifdef PROPAGATE_SPOOF sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s DELSPOOF %s@%s", source_p->name, user, host); #endif #ifdef SPOOF_FILE if ((f = fbopen(SPOOF_FILE, "r")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not open %s file, auth for %s@%s not deleted " "(requested by %s)", SPOOF_FILE, user, host, source_p->name); return; } if ((fout = fbopen(SPOOF_FILE ".new", "w")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not create %s.new file, auth for %s@%s not " "deleted (requested by %s)", SPOOF_FILE, user, host, source_p->name); return; } while (fbgets(buffer, 1024, f)) { if (!ircncmp(buffer, "auth {", 6)) { /* don't process it yet.. we have to check whether the user="******"; field * matches the user@host mask which is being deleted */ ignore_it = 1; continue; } /* a simple parser substitute... */ for (tmp = buffer; *tmp == '\t' || *tmp == ' '; tmp++) ; if (!ircncmp(tmp, "user", 4)) { for (tmp += 4; *tmp == '\t' || *tmp == ' '; tmp++) ; if (*tmp == '=') { for (++tmp; *tmp == '\t' || *tmp == ' '; tmp++) ; if (*tmp == '\"') { /* yuppi, we've just reached the user="******"; field */ int matches; char *tmp2 = strchr(++tmp, '\"'); if (tmp2 != NULL) *tmp2 = '\0'; tmp2 = strchr(tmp, '@'); /* is it matching our mask? */ if (tmp2 == NULL) matches = !irccmp(user, "*") && !irccmp(host, tmp); else { *tmp2++ = '\0'; matches = !irccmp(user, tmp) && !irccmp(host, tmp2); } if (!matches) { /* no.. so leave it unchanged */ if (ignore_it) { ignore_it = 0; fbputs("auth {\n", fout, 7); /* user="******" should be the first field in the auth {}; block, * otherwise we could have problems... */ } fbputs("\tuser = \"", fout, 9); if (tmp2 == NULL) fbputs("*", fout, 1); else fbputs(tmp, fout, strlen(tmp)); fbputs("@", fout, 1); fbputs(tmp2, fout, strlen(tmp2)); fbputs("\";\n", fout, 3); } else { /* we've got it! - omit and continue working */ spoof_found = 1; } continue; } } } if (!ignore_it) fbputs(buffer, fout, strlen(buffer)); } fbclose(f); fbclose(fout); if (!spoof_found) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :No auth for %s@%s found", me.name, source_p->name, user, host); unlink(SPOOF_FILE ".new"); return; } unlink(SPOOF_FILE); rename(SPOOF_FILE ".new", SPOOF_FILE); rehash(0); #endif #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s deleted auth for %s@%s", source_p->name, user, host); #endif }
/* parse_csv_file() * * inputs - FILE pointer * - type of conf to parse * output - none * side effects - */ void parse_csv_file(FBFILE *file, ConfType conf_type) { struct ConfItem *conf; struct AccessItem *aconf; struct MatchItem *match_item; struct MatchItem *nresv; struct ResvChannel *cresv; char *name_field=NULL; char *user_field=NULL; char *reason_field=NULL; char *oper_reason=NULL; char *host_field=NULL; char *duration_field=NULL; char *temp=NULL; char line[IRCD_BUFSIZE]; char *p; while (fbgets(line, sizeof(line), file) != NULL) { duration_field = NULL; if ((p = strchr(line, '\n')) != NULL) *p = '\0'; if ((line[0] == '\0') || (line[0] == '#')) continue; switch(conf_type) { case KLINE_TYPE: parse_csv_line(line, &user_field, &host_field, &reason_field, &oper_reason, &temp, &temp, &temp, &duration_field, NULL); conf = make_conf_item(KLINE_TYPE); aconf = map_to_conf(conf); if (host_field != NULL) DupString(aconf->host, host_field); if (reason_field != NULL) DupString(aconf->reason, reason_field); if (oper_reason != NULL) DupString(aconf->oper_reason, oper_reason); if (user_field != NULL) DupString(aconf->user, user_field); if (duration_field != NULL) aconf->hold = atoi(duration_field); if (aconf->host != NULL) { if(duration_field == NULL) add_conf_by_address(CONF_KILL, aconf); else add_temp_line(conf); } break; case RKLINE_TYPE: { const char *errptr = NULL; pcre *exp_user = NULL, *exp_host = NULL; parse_csv_line(line, &user_field, &host_field, &reason_field, &oper_reason, &temp, &temp, &temp, &duration_field, NULL); if (host_field == NULL || user_field == NULL) break; if (!(exp_user = ircd_pcre_compile(user_field, &errptr)) || !(exp_host = ircd_pcre_compile(host_field, &errptr))) { sendto_realops_flags(UMODE_ALL, L_ALL, "Failed to add regular expression based K-Line: %s", errptr); break; } conf = make_conf_item(RKLINE_TYPE); aconf = map_to_conf(conf); aconf->regexuser = exp_user; aconf->regexhost = exp_host; DupString(aconf->user, user_field); DupString(aconf->host, host_field); if (reason_field != NULL) DupString(aconf->reason, reason_field); else DupString(aconf->reason, "No reason"); if (oper_reason != NULL) DupString(aconf->oper_reason, oper_reason); if(duration_field != NULL) { aconf->hold = atoi(duration_field); add_temp_line(conf); } } break; case DLINE_TYPE: parse_csv_line(line, &host_field, &reason_field, &temp, &temp, &temp, &temp, &duration_field, NULL); conf = make_conf_item(DLINE_TYPE); aconf = (struct AccessItem *)map_to_conf(conf); if (host_field != NULL) DupString(aconf->host, host_field); if (reason_field != NULL) DupString(aconf->reason, reason_field); if(duration_field != NULL) { aconf->hold = atoi(duration_field); add_temp_line(conf); } else conf_add_d_conf(aconf); break; case XLINE_TYPE: parse_csv_line(line, &name_field, &reason_field, &oper_reason, &temp, &temp, &temp, &temp, &duration_field, NULL); conf = make_conf_item(XLINE_TYPE); match_item = (struct MatchItem *)map_to_conf(conf); if (name_field != NULL) DupString(conf->name, name_field); if (reason_field != NULL) DupString(match_item->reason, reason_field); if(duration_field != NULL) { match_item->hold = atoi(duration_field); add_temp_line(conf); } break; case RXLINE_TYPE: { const char *errptr = NULL; pcre *exp_p = NULL; parse_csv_line(line, &name_field, &reason_field, &oper_reason, &temp, &temp, &temp, &temp, &duration_field, NULL); if (name_field == NULL) break; if (!(exp_p = ircd_pcre_compile(name_field, &errptr))) { sendto_realops_flags(UMODE_ALL, L_ALL, "Failed to add regular expression based X-Line: %s", errptr); break; } conf = make_conf_item(RXLINE_TYPE); conf->regexpname = exp_p; match_item = map_to_conf(conf); DupString(conf->name, name_field); if (reason_field != NULL) DupString(match_item->reason, reason_field); else DupString(match_item->reason, "No reason"); if(duration_field != NULL) { match_item->hold = atoi(duration_field); add_temp_line(conf); } } break; case CRESV_TYPE: parse_csv_line(line, &name_field, &reason_field, &duration_field, NULL); conf = create_channel_resv(name_field, reason_field, 0); if(duration_field != NULL) { cresv = map_to_conf(conf); cresv->hold = atoi(duration_field); add_temp_line(conf); } break; case NRESV_TYPE: parse_csv_line(line, &name_field, &reason_field, &duration_field, NULL); conf = create_nick_resv(name_field, reason_field, 0); if(duration_field != NULL) { nresv = map_to_conf(conf); nresv->hold = atoi(duration_field); add_temp_line(conf); } break; case GLINE_TYPE: case GDENY_TYPE: case CONF_TYPE: case OPER_TYPE: case CLIENT_TYPE: case SERVER_TYPE: case CLUSTER_TYPE: case HUB_TYPE: case LEAF_TYPE: case ULINE_TYPE: case EXEMPTDLINE_TYPE: case CLASS_TYPE: break; } } }
/* * read_message_file() - original From CoMSTuD, added Aug 29, 1996 * * inputs - pointer to MessageFileptr * output - * side effects - */ int read_message_file(MessageFile *MessageFileptr) { struct stat sb; struct tm *local_tm; /* used to clear out old MessageFile entries */ MessageFileLine *mptr = 0; MessageFileLine *next_mptr = 0; /* used to add new MessageFile entries */ MessageFileLine *newMessageLine = 0; MessageFileLine *currentMessageLine = 0; char buffer[MESSAGELINELEN]; char *p; FBFILE *file; for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) { next_mptr = mptr->next; MyFree(mptr); } MessageFileptr->contentsOfFile = NULL; if (stat(MessageFileptr->fileName, &sb) < 0) return(-1); local_tm = localtime(&sb.st_mtime); if (local_tm) ircsprintf(MessageFileptr->lastChangedDate, "%d/%d/%d %d:%02d", local_tm->tm_mday, local_tm->tm_mon + 1, 1900 + local_tm->tm_year, local_tm->tm_hour, local_tm->tm_min); if ((file = fbopen(MessageFileptr->fileName, "r")) == NULL) return(-1); while (fbgets(buffer, sizeof(buffer), file)) { if ((p = strchr(buffer, '\n')) != NULL) *p = '\0'; newMessageLine = (MessageFileLine *)MyMalloc(sizeof(MessageFileLine)); strlcpy(newMessageLine->line, buffer, sizeof(newMessageLine->line)); newMessageLine->next = NULL; if (MessageFileptr->contentsOfFile != NULL) { if (currentMessageLine) currentMessageLine->next = newMessageLine; currentMessageLine = newMessageLine; } else { MessageFileptr->contentsOfFile = newMessageLine; currentMessageLine = newMessageLine; } } fbclose(file); return(0); }
/** This function reads a motd out of a file (if needed) and caches it. * If a matching cache entry already exists, reuse it. Otherwise, * allocate and populate a new MotdCache for it. * @param[in] motd Specification for MOTD file. * @return Matching MotdCache entry. */ static struct MotdCache * motd_cache(struct Motd *motd) { FBFILE* file; struct MotdCache* cache; struct stat sb; char line[MOTD_LINESIZE + 2]; /* \r\n */ char* tmp; int i; assert(0 != motd); assert(0 != motd->path); if (motd->cache) return motd->cache; /* try to find it in the list of cached files... */ for (cache = MotdList.cachelist; cache; cache = cache->next) { if (!strcmp(cache->path, motd->path) && cache->maxcount == motd->maxcount) { /* found one... */ cache->ref++; /* increase reference count... */ motd->cache = cache; /* remember cache... */ return motd->cache; /* return it */ } } /* gotta read in the file, now */ if (!(file = fbopen(motd->path, "r"))) { Debug((DEBUG_ERROR, "Couldn't open \"%s\": %s", motd->path, strerror(errno))); return 0; } /* need the file's modification time */ if (-1 == fbstat(&sb, file)) { fbclose(file); return 0; } /* Ok, allocate a structure; we'll realloc later to trim memory */ cache = (struct MotdCache *)MyMalloc(sizeof(struct MotdCache) + (MOTD_LINESIZE * (MOTD_MAXLINES - 1))); cache->ref = 1; DupString(cache->path, motd->path); cache->maxcount = motd->maxcount; cache->modtime = *localtime((time_t *) &sb.st_mtime); /* store modtime */ cache->count = 0; while (cache->count < cache->maxcount && fbgets(line, sizeof(line), file)) { /* copy over line, stopping when we overflow or hit line end */ for (tmp = line, i = 0; i < (MOTD_LINESIZE - 1) && *tmp && *tmp != '\r' && *tmp != '\n'; tmp++, i++) cache->motd[cache->count][i] = *tmp; cache->motd[cache->count][i] = '\0'; cache->count++; } fbclose(file); /* close the file */ /* trim memory usage a little */ motd->cache = (struct MotdCache*)MyMalloc(sizeof(struct MotdCache) + (MOTD_LINESIZE * (cache->count - 1))); memcpy(motd->cache, cache, sizeof(struct MotdCache) + (MOTD_LINESIZE * (cache->count - 1))); MyFree(cache); /* now link it in... */ motd->cache->next = MotdList.cachelist; motd->cache->prev_p = &MotdList.cachelist; if (MotdList.cachelist) MotdList.cachelist->prev_p = &motd->cache->next; MotdList.cachelist = motd->cache; return motd->cache; }