static void check_registration(hook_user_register_check_t *hdata) { char buf[1024]; const char *user; const char *domain; int count; pid_t pid; struct procdata *pd; if (hdata->approved) return; if (proccount >= MAX_CHILDPROCS) { command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later."); hdata->approved = 1; return; } switch (pid = fork()) { case 0: /* child */ connection_close_all_fds(); mowgli_strlcpy(buf, hdata->email, sizeof buf); user = strtok(buf, "@"); domain = strtok(NULL, "@"); count = count_mx(domain); if (count <= 0) { /* no MX records or error */ struct hostent *host; /* attempt to resolve host (fallback to A) */ if((host = gethostbyname(domain)) == NULL) _exit(1); } _exit(0); break; case -1: /* error */ slog(LG_ERROR, "fork() failed for check_registration(): %s", strerror(errno)); command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later."); hdata->approved = 1; return; default: /* parent */ pd = &procdata[proccount++]; mowgli_strlcpy(pd->name, hdata->account, sizeof pd->name); mowgli_strlcpy(pd->email, hdata->email, sizeof pd->email); childproc_add(pid, "ns_mxcheck_async", childproc_cb, pd); return; } }
static void on_db_save(void *unused) { int stdout_pipes[2], stderr_pipes[2]; pid_t pid; int errno1; if (!command) return; if (update_command_proc.running) { slog(LG_ERROR, "ERROR: database update command is still running"); return; } if (pipe(stdout_pipes) == -1) { int err = errno; slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err)); return; } if (pipe(stderr_pipes) == -1) { int err = errno; slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err)); close(stdout_pipes[0]); close(stdout_pipes[1]); return; } pid = fork(); switch (pid) { case -1: errno1 = errno; slog(LG_ERROR, "Failed to fork for database update command: %s", strerror(errno1)); return; case 0: connection_close_all_fds(); close(stdout_pipes[0]); close(stderr_pipes[0]); dup2(stdout_pipes[1], 1); dup2(stderr_pipes[1], 2); close(stdout_pipes[1]); close(stderr_pipes[1]); execl("/bin/sh", "sh", "-c", command, NULL); write(2, "Failed to exec /bin/sh\n", 23); _exit(255); return; default: close(stdout_pipes[1]); close(stderr_pipes[1]); update_command_proc.out = connection_add("update_command_stdout", stdout_pipes[0], 0, recvq_put, NULL); update_command_proc.err = connection_add("update_command_stderr", stderr_pipes[0], 0, recvq_put, NULL); update_command_proc.out->recvq_handler = update_command_stdout_handler; update_command_proc.err->recvq_handler = update_command_stderr_handler; update_command_proc.pid = pid; update_command_proc.running = 1; childproc_add(pid, "db_update", update_command_finished, NULL); break; } }