static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct mog_cfg *cfg = state->input; int rv = 0; switch (key) { case 'd': cfg->daemonize = true; break; case 's': /* no-op, we don't load the default config file */; break; case CFG_KEY(docroot): cfg->docroot = xstrdup(arg); break; case CFG_KEY(pidfile): cfg->pidfile = xstrdup(arg); break; case CFG_KEY(configfile): new_cfg_or_die(arg); break; case CFG_KEY(maxconns): check_strtoul(&cfg->maxconns, arg, "maxconns"); break; case CFG_KEY(httplisten): addr_or_die(&cfg->httplisten, "httplisten", arg); break; case CFG_KEY(mgmtlisten): addr_or_die(&cfg->mgmtlisten, "mgmtlisten", arg); break; case CFG_KEY(server): cfg->server = xstrdup(arg); mog_cfg_check_server(cfg); break; case -'M': mog_cfg_multi = true; break; case -'W': check_strtoul(&worker_processes, arg, "worker-processes"); if (worker_processes > UINT_MAX) die("--worker-processes exceeded (max=%u)", UINT_MAX); break; case ARGP_KEY_ARG: argp_usage(state); case ARGP_KEY_END: break; default: rv = ARGP_ERR_UNKNOWN; } return rv; }
int pptpd_reload(pptpd *_this, struct properties *config, const char *name, int default_enabled) { int i, do_start, aierr; const char *val; char *tok, *cp, buf[PPTPD_CONFIG_BUFSIZ], *label; struct addrinfo *ai; ASSERT(_this != NULL); ASSERT(config != NULL); _this->config = config; do_start = 0; if (pptpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true", default_enabled)) { /* avoid false-true flap */ if (pptpd_is_shutting_down(_this)) pptpd_stop_immediatly(_this); if (pptpd_is_stopped(_this)) do_start = 1; } else { if (!pptpd_is_stopped(_this)) pptpd_stop(_this); return 0; } if (do_start && pptpd_init(_this) != 0) return 1; /* set again as pptpd_init will reset it */ _this->config = config; _this->ctrl_in_pktdump = pptpd_config_str_equal(_this, "log.pptp.ctrl.in.pktdump", "true", 0); _this->data_in_pktdump = pptpd_config_str_equal(_this, "log.pptp.data.in.pktdump", "true", 0); _this->ctrl_out_pktdump = pptpd_config_str_equal(_this, "log.pptp.ctrl.out.pktdump", "true", 0); _this->data_out_pktdump = pptpd_config_str_equal(_this, "log.pptp.data.out.pktdump", "true", 0); _this->phy_label_with_ifname = pptpd_config_str_equal(_this, CFG_KEY(name, "label_with_ifname"), "true", 0); /* parse ip4_allow */ in_addr_range_list_remove_all(&_this->ip4_allow); val = pptpd_config_str(_this, CFG_KEY(name, "ip4_allow")); if (val != NULL) { if (strlen(val) >= sizeof(buf)) { log_printf(LOG_ERR, "configuration error at " "%s: too long", CFG_KEY(name, "ip4_allow")); return 1; } strlcpy(buf, val, sizeof(buf)); for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) { if (*tok == '\0') continue; if (in_addr_range_list_add(&_this->ip4_allow, tok) != 0) { pptpd_log(_this, LOG_ERR, "configuration error at %s: %s", CFG_KEY(name, "ip4_allow"), tok); return 1; } } } if (do_start) { /* in the case of 1) cold-booted and 2) pptpd.enable * toggled "false" to "true" do this, because we can * assume that all pptpd listner are initialized. */ val = pptpd_config_str(_this, CFG_KEY(name, "listener_in")); if (val != NULL) { if (strlen(val) >= sizeof(buf)) { pptpd_log(_this, LOG_ERR, "configuration error at " "%s: too long", CFG_KEY(name, "listener")); return 1; } strlcpy(buf, val, sizeof(buf)); label = NULL; /* it can accept multple velues with tab/space * separation */ for (i = 0, cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) { if (*tok == '\0') continue; if (label == NULL) { label = tok; continue; } if ((aierr = addrport_parse(tok, IPPROTO_TCP, &ai)) != 0) { pptpd_log(_this, LOG_ERR, "configuration error at " "%s: %s: %s", CFG_KEY(name, "listener_in"), tok, gai_strerror(aierr)); return 1; } PPTPD_ASSERT(ai != NULL && ai->ai_family == AF_INET); if (pptpd_add_listener(_this, i, label, ai->ai_addr) != 0) { freeaddrinfo(ai); label = NULL; break; } freeaddrinfo(ai); label = NULL; i++; } if (label != NULL) { pptpd_log(_this, LOG_ERR, "configuration error at %s: %s", CFG_KEY(name, "listner_in"), label); return 1; } } if (pptpd_start(_this) != 0) return 1; } return 0; }
static struct mog_fd *master_selfwake; static sig_atomic_t sigchld_hit; static sig_atomic_t do_exit; static sig_atomic_t do_upgrade; static size_t nthr; static bool have_mgmt; static pid_t master_pid; static pid_t upgrade_pid; static unsigned long worker_processes; static bool iostat_running; #define CFG_KEY(f) -((int)offsetof(struct mog_cfg,f) + 1) static struct argp_option options[] = { { .name = "daemonize", .key = 'd', .doc = "Daemonize" }, { .name = "config", .key = CFG_KEY(configfile), .arg = "<file>", .doc = "Set config file (no default, unlike mogstored)" }, { .name = "httplisten", .key = CFG_KEY(httplisten), .arg = "<ip:port>", .doc = "IP/Port HTTP server listens on" }, /* * NOT adding httpgetlisten here to avoid (further) breaking * compatibility with Perl mogstored. Most of these command-line * options suck anyways. */ { .name = "mgmtlisten", .key = CFG_KEY(mgmtlisten), .arg = "<ip:port>", .doc = "IP/Port management/sidechannel listens on" }, { .name = "docroot", .key = CFG_KEY(docroot), .arg = "<path>",
/* * This is the back end for flush_conversations_to_disk() * At this point we've isolated a single conversation (struct imlog) * and are ready to write it to disk. */ void flush_individual_conversation(struct imlog *im) { struct CtdlMessage *msg; long msgnum = 0; char roomname[ROOMNAMELEN]; StrBuf *MsgBuf, *FullMsgBuf; StrBufAppendBufPlain(im->conversation, HKEY( "</body>\r\n" "</html>\r\n" ), 0 ); MsgBuf = StrBufRFC2047encodeMessage(im->conversation); FlushStrBuf(im->conversation); FullMsgBuf = NewStrBufPlain(NULL, StrLength(im->conversation) + 100); StrBufAppendBufPlain(FullMsgBuf, HKEY( "Content-type: text/html; charset=UTF-8\r\n" "Content-Transfer-Encoding: quoted-printable\r\n" "\r\n" ), 0); StrBufAppendBuf (FullMsgBuf, MsgBuf, 0); FreeStrBuf(&MsgBuf); msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = FMT_RFC822; if (!IsEmptyStr(im->usernames[0])) { CM_SetField(msg, eAuthor, im->usernames[0], strlen(im->usernames[0])); } else { CM_SetField(msg, eAuthor, HKEY("Citadel")); } if (!IsEmptyStr(im->usernames[1])) { CM_SetField(msg, eRecipient, im->usernames[1], strlen(im->usernames[1])); } CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM)); CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); CM_SetAsFieldSB(msg, eMesageText, &FullMsgBuf); /* we own this memory now */ /* Start with usernums[1] because it's guaranteed to be higher than usernums[0], * so if there's only one party, usernums[0] will be zero but usernums[1] won't. * Create the room if necessary. Note that we create as a type 5 room rather * than 4, which indicates that it's a personal room but we've already supplied * the namespace prefix. * * In the unlikely event that usernums[1] is zero, a room with an invalid namespace * prefix will be created. That's ok because the auto-purger will clean it up later. */ snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[1], PAGELOGROOM); CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS); msgnum = CtdlSubmitMsg(msg, NULL, roomname, 0); CM_Free(msg); /* If there is a valid user number in usernums[0], save a copy for them too. */ if (im->usernums[0] > 0) { snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[0], PAGELOGROOM); CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS); CtdlSaveMsgPointerInRoom(roomname, msgnum, 0, NULL); } /* Finally, if we're logging instant messages globally, do that now. */ if (!IsEmptyStr(config.c_logpages)) { CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS); CtdlSaveMsgPointerInRoom(config.c_logpages, msgnum, 0, NULL); } }