/* This function could, at the time of writing this comment, sanely handle SRC_ANY, but ts6-protocol.txt says that TOPIC can only come from users */ static int c_u_topic(u_sourceinfo *si, u_msg *msg) { u_chan *c; u_chanuser *cu; if (!(c = u_chan_get(msg->argv[0]))) return u_src_num(si, ERR_NOSUCHCHANNEL, msg->argv[0]); cu = u_chan_user_find(c, si->u); if (msg->argc == 1) { if (!cu && (c->mode & CMODE_SECRET)) return u_src_num(si, ERR_NOTONCHANNEL, c); return u_chan_send_topic(c, si->u); } if (SRC_IS_LOCAL_USER(si)) { if (!cu) return u_src_num(si, ERR_NOTONCHANNEL, c); else if ((c->mode & CMODE_TOPIC) && !(cu->flags & CU_PFX_OP)) return u_src_num(si, ERR_CHANOPRIVSNEEDED, c); } u_strlcpy(c->topic, msg->argv[1], MAXTOPICLEN+1); u_strlcpy(c->topic_setter, (char*)si->name, MAXNICKLEN+1); c->topic_time = NOW.tv_sec; u_sendto_chan(c, NULL, ST_USERS, ":%I TOPIC %C :%s", si, c, c->topic); u_sendto_servers(si->source, ":%I TOPIC %C :%s", si, c, c->topic); return 0; }
static int c_s_tb(u_sourceinfo *si, u_msg *msg) { char *chan = msg->argv[0]; int ts; u_chan *c; msg->propagate = CMD_DO_BROADCAST; if (!(c = u_chan_get(chan))) { u_log(LG_WARN, "%I sent TB for nonexistent %s", si, chan); return 0; } ts = atoi(msg->argv[1]); /* TODO: TS checking */ c->topic_time = ts; if (msg->argc > 3) { u_strlcpy(c->topic_setter, msg->argv[2], MAXNICKLEN+1); } else { snf(FMT_USER, c->topic_setter, MAXNICKLEN+1, "%I", si); } u_strlcpy(c->topic, msg->argv[msg->argc - 1], MAXTOPICLEN+1); u_sendto_chan(c, NULL, ST_USERS, ":%I TOPIC %C :%s", si, c, c->topic); return 0; }
/** * \brief Convert a \c time_t value to a rfc822 time string * * Convert the \c time_t value \p ts to a rfc822 time string * * \param dst placeholder for the rfc822 time string. The buffer, * of at least RFC822_DATE_BUFSZ bytes, must be preallocated * by the caller. * \param ts the \c time_t value to be converted * * \return * - \c 0 successful * - \c ~0 failure */ int u_tt_to_rfc822(char dst[RFC822_DATE_BUFSZ], time_t ts) { char buf[RFC822_DATE_BUFSZ]; struct tm tm; dbg_return_if (dst == NULL, ~0); #ifdef OS_WIN memcpy(&tm, gmtime(&ts), sizeof(tm)); #else dbg_err_if(gmtime_r(&ts, &tm) == NULL); #endif dbg_err_if(tm.tm_wday > 6 || tm.tm_wday < 0); dbg_err_if(tm.tm_mon > 11 || tm.tm_mon < 0); dbg_err_if(u_snprintf(buf, sizeof buf, "%s, %02u %s %02u %02u:%02u:%02u GMT", days3[tm.tm_wday], tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec)); /* copy out */ u_strlcpy(dst, buf, RFC822_DATE_BUFSZ); return 0; err: return ~0; }
static void print_header(parser_t *p, lang_c_ctx_t *ctx) { static const char dfun_prefix[] = "page_"; const char *file; char *dfun; int i; dbg_ifb (p == NULL) return; dbg_ifb (ctx == NULL) return; (void)ctx; io_printf(p->out, "%s", copyright_hdr); io_printf(p->out, "#include <klone/emb.h>\n"); io_printf(p->out, "#include <klone/dypage.h>\n"); file = ctx->ti->uri + strlen(ctx->ti->uri) - 1; for(; *file != '/' && file >= ctx->ti->uri; --file) ; io_printf(p->out, "static const char *SCRIPT_NAME = \"%s\";\n", ++file); dfun = ctx->ti->dfun; /* shortcut */ /* we need a prefix to avoid errors with pages whose filename starts with a number (404-handler.kl1) or any other char not allowed by C as the first char of function names */ (void) u_strlcpy(dfun, dfun_prefix, URI_BUFSZ); dbg_if (u_strlcat(dfun, file, URI_BUFSZ)); for(i = 0; i < (int) strlen(dfun); ++i) if(!isalnum(dfun[i])) dfun[i] = '_'; /* just a-zA-Z0-9 allowed */ /* add a dummy function that the user can use to set a breakpoint when entering the page code. the "static volatile" variable is used to avoid the compiler to optimize-out (inlining) the function call */ io_printf(p->out, "static int %s (void) { " "static volatile int dummy; return dummy; }\n", dfun); io_printf(p->out, "static request_t *request = NULL;\n" "static response_t *response = NULL;\n" "static session_t *session = NULL;\n" "static io_t *in = NULL;\n" "static io_t *out = NULL;\n"); return; }
/* add an atom to the list of global atoms */ static int session_mem_add(session_opt_t *so, const char *filename, char *buf, size_t size, time_t mtime) { atom_t *atom = NULL; enc_ses_mem_t *esm = NULL; ppc_t *ppc; size_t esize; dbg_err_if (so == NULL); dbg_err_if (filename == NULL); dbg_err_if (buf == NULL); if(ctx->pipc) { /* children context */ ppc = server_get_ppc(ctx->server); dbg_err_if(ppc == NULL); /* build the encoded parameters structure */ esize = size + sizeof(enc_ses_mem_t); esm = (enc_ses_mem_t*)u_malloc(esize); dbg_err_if(esm == NULL); /* fill esm fields */ esm->mtime = time(0); esm->size = size; dbg_err_if(strlen(filename) > SESSION_FILENAME_MAX_LENGTH); u_strlcpy(esm->filename, filename, sizeof esm->filename); memcpy(esm->data, buf, size); /* send the command request */ dbg_err_if(ppc_write(ppc, ctx->pipc, PPC_CMD_MSES_SAVE, (char*)esm, esize) < 0); U_FREE(esm); /* add it to the local copy of atom list */ dbg_err_if(so_atom_add(so, filename, buf, size, (void*)mtime)); } else { /* parent context */ dbg_err_if(so_atom_add(so, filename, buf, size, (void*)mtime)); } return 0; err: U_FREE(esm); if(atom) atom_free(atom); return ~0; }
/* [parent] get session data */ static int session_cmd_get(ppc_t *ppc, int fd, unsigned char cmd, char *data, size_t size, void *vso) { enum { BUFSZ = 4096 }; session_opt_t *so = vso; enc_ses_mem_t *esm = NULL; atom_t *atom = NULL; char buf[BUFSZ]; size_t esm_size; u_unused_args(cmd, size); dbg_err_if (ppc == NULL); dbg_err_if (vso == NULL); dbg_err_if (data == NULL); dbg_err_if (strlen(data) > SESSION_FILENAME_MAX_LENGTH); /* find the atom whose name is stored into 'data' buffer */ nop_err_if(atoms_get(so->atoms, data, &atom)); /* if the buffer on the stack is big enough use it, otherwise alloc a bigger one on the heap */ if((esm_size = sizeof(enc_ses_mem_t) + atom->size) > BUFSZ) { esm = u_malloc(1 + esm_size); dbg_err_if(esm == NULL); } else esm = (enc_ses_mem_t*)buf; /* fill the enc_ses_mem_t struct */ esm->mtime = (time_t)atom->arg; u_strlcpy(esm->filename, data, sizeof esm->filename); esm->size = atom->size; memcpy(esm->data, atom->data, atom->size); dbg_err_if(ppc_write(ppc, fd, PPC_CMD_RESPONSE_OK, (char*)esm, esm_size) <= 0); if(esm && esm != (void*)buf) U_FREE(esm); return 0; err: if(ppc) ppc_write(ppc, fd, PPC_CMD_RESPONSE_ERROR, (char *)"", 1); if(esm && esm != (void *)buf) U_FREE(esm); return ~0; }
static void cmp_last_string (u_bst_node_t *node, void *p) { u_test_case_t *tc = (u_test_case_t *) p; const char *key = (const char *) u_bst_node_key(node); static char last[KEY_SZ] = { '\0' }; /* Compare against last saved key. */ if (strcmp(last, key) > 0) { /* FIXME: on failure should fire an abort() or set some global * to explicitly invalidate the test. */ u_test_case_printf(tc, "SORT FAILED on key %s", key); } /* Save current node's key to 'last'. */ (void) u_strlcpy(last, key, sizeof last); return ; }
ec_res_t *ec_resource_new(const char *uri, ec_method_mask_t methods, uint32_t max_age) { ec_res_t *res = NULL; dbg_return_if (uri == NULL, NULL); dbg_return_if (!(EC_IS_METHOD_MASK(methods)), NULL); dbg_err_sif ((res = u_zalloc(sizeof *res)) == NULL); dbg_err_if (u_strlcpy(res->uri, uri, sizeof res->uri)); res->methods = methods; res->max_age = max_age ? max_age : EC_COAP_DEFAULT_MAX_AGE; TAILQ_INIT(&res->reps); (void) ec_res_attrs_init(res); return res; err: if (res) ec_resource_free(res); return NULL; }
void u_ntop(struct in_addr *in, char *s) { u_strlcpy(s, inet_ntoa(*in), INET_ADDRSTRLEN); }
void u_strlcat(char *dest, char *src, ulong n) { int len = strlen(dest); u_strlcpy(dest+len, src, n-len); }
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { SERVICE_TABLE_ENTRY ServiceTable[] = { { ss_name, ServiceMain }, { NULL, NULL } /* end of list */ }; int rc = 0; const char *name, *desc; memset(ctx, 0, sizeof(context_t)); /* parse command line parameters (and set ctx vars). NOTE: this work only if launched by command line, for services see ServiceMain */ dbg_err_if(parse_opt(__argc, __argv)); if(ctx->serv_op) { /* load config and initialize */ dbg_err_if(app_init()); /* set up service name and description reading from the config file */ name = u_config_get_subkey_value(ctx->config, "daemon.name"); if(name) u_strlcpy(ss_name, name, sizeof ss_name); desc = u_config_get_subkey_value(ctx->config, "daemon.description"); if(desc) u_strlcpy(ss_desc, desc, sizeof ss_desc); if(ctx->serv_op == SERV_INSTALL) dbg_err_if(InstallService()); else dbg_err_if(RemoveService()); } else if(ctx->daemon) { u_dbg("Starting in service mode..."); /* StartServiceCtrlDispatcher does not return until the service has stopped running... */ if(!StartServiceCtrlDispatcher(ServiceTable)) warn_strerror(GetLastError()); } else { /* load config and initialize */ dbg_err_if(app_init()); rc = app_run(); } dbg_err_if(app_term()); /* if debugging then call exit(3) because it's needed to gprof to dump its stats file (gmon.out) */ if(ctx->debug) return rc; /* don't use return because exit(3) will be called and we don't want FILE* buffers to be automatically flushed (klog_file_t will write same lines more times, once by the parent process and N times by any child created when FILE buffer was not empty) */ _exit(rc); err: app_term(); if(ctx->debug) return rc; _exit(EXIT_FAILURE); }