int main(int argc, char **argv) { int sockfd, new_fd,numbytes; // listen on sock_fd, new connection on new_fd char buf[MAXDATASIZE]; struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv,tempType=0; pid_t tempPid; PACKET tempPacket; if (argc==2 && (strcmp("-d",argv[1])==0)) { printf("== Daemon mode selected.==\n"); daemonFlag=1; } if (daemonFlag) { // Become a daemon: switch (fork ()) { case -1: // can't fork perror ("fork()"); exit (0); case 0: // child, process becomes a daemon: close (STDIN_FILENO); close (STDOUT_FILENO); close (STDERR_FILENO); if (setsid () == -1) // request a new session (job control) { exit (0); } break; default: // parent returns to calling process: return 0; } // Establish signal handler to clean up before termination: if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN); signal (SIGINT, SIG_IGN); signal (SIGHUP, SIG_IGN); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } printf("server(%d): waiting for connections...\n",getpid()); while(keep_going) { // main accept() loop sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("server(%d): got connection from %s\n", getpid(),s); if (!fork()) { // this is the child process close(sockfd); // child doesn't need this descriptor openlog("DaemonServer",LOG_PID,LOG_SYSLOG); while (tempType!=2) {//child stops when client deregisters //recv packet if (recv(new_fd, (void*)&tempPacket, sizeof(tempPacket), 0) == -1) { perror("recv"); break; } tempType=tempPacket.packet_head.type; tempPid=tempPacket.packet_head.sender_pid; if (tempType<=3) { printf("server(%d): received msg type:'%d' from %s-client(%d) \n",getpid(), tempType,tempPacket.packet_head.mid,tempPid); syslog(LOG_NOTICE, "server(%d): received msg type:'%d' from %s-client(%d) \n",getpid(), tempType,tempPacket.packet_head.mid,tempPid); if (tempType==MSG_HEAD_NORMAL) { printf("server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); syslog(LOG_NOTICE, "server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); } //generate ACKs printf("server(%d): sent ACK type:'%d' to %s-client(%d)\n",getpid(), tempType+3,tempPacket.packet_head.mid,tempPid); syslog(LOG_NOTICE, "server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); generatePacket(&tempPacket, tempType+3, getpid(), "Server"); //send acks if (send(new_fd, (void*)&tempPacket, sizeof(tempPacket), 0) == -1) { perror("send"); break; } } } closelog(); close(new_fd); exit(0); } close(new_fd); // parent doesn't need this } return 0; }
/* lpty_startproc * * start a process with our pty as its controlling terminal. * * Arguments: * L Lua State * * Lua Stack: * 1 lpty userdata * * Lua Returns: * +1 false if the re was already an active subprocess of this pty, true if * not and we started one. * * Note: * We can not determine wether the command to be spawned in the child process * was successful. */ static int lpty_startproc(lua_State *L) { lPty *pty = lpty_checkLPty(L, 1); const char *cmd = luaL_checkstring(L, 2); /* if pty already has an active child process we just return false and do * nothing */ if (_lpty_hasrunningchild(pty)) lua_pushboolean(L, 0); else { pid_t child; int ttyfd = pty->s_fd; _lpty_set_sigchld_handler(_lpty_sigchld_handler); /* now start child process */ child = fork(); if (child == 0) { /* child process */ /* fill execvp args array from function arguments */ int nargs = lua_gettop(L) - 1; const char **args = calloc(nargs + 1, sizeof(char*)); int i; args[0] = cmd; for (i = 1; i < nargs; ++i) args[i] = lua_tostring(L, 2 + i); args[nargs] = NULL; /* suppress local echo on slave side if wanted */ if (pty->flags.nolocalecho) _lpty_tsetnoecho(pty); /* put terminal into raw mode if wanted */ if (pty->flags.rawmode) _lpty_tsetraw(pty); /* prepare child processes standard file handles */ dup2(ttyfd, 0); dup2(ttyfd, 1); if (pty->e_sfd > 0) dup2(pty->e_sfd, 2); else dup2(ttyfd, 2); /* need to create new session id for slave in order for the tty to * become a controlling tty */ if (setsid() < (pid_t)0) { fprintf(stderr, "error: lpty failed to create new session id."); exit(EXIT_FAILURE); /* we need to terminate here! */ } /* now make our tty the controlling tty for the new session */ if(ioctl(ttyfd,TIOCSCTTY,1)) { fprintf(stderr, "error: lpty failed to set the controlling tty."); exit(EXIT_FAILURE); } /* reset SIGCHLD handler then start our process */ _lpty_set_sigchld_handler(SIG_DFL); char **e = _lpty_makeenv(L); if (pty->flags.usepath) _lpty_execvpe(cmd, (char* const*)args, e ? e : environ); else execve(cmd, (char* const*)args, e ? e : environ); _lpty_freeenv(e); /* if we ever get here, an error has occurred. * Note: this error will only be visible as output to the pty from the parent side! */ free(args); fprintf(stderr, "error: lpty failed to start child process: %s", strerror(errno)); exit(EXIT_FAILURE); /* we need to terminate here! */ } else if (child > 0) { /* parent process: clean up, store child pid, return success */ pty->child = child; lua_pushboolean(L, 1); } else { return _lpty_error(L, pty->flags.throwerrors, "lpty failed to create child process: %s", strerror(errno)); } } return 1; }
int main(int argc, char **argv) { char inpstr[2000], authstr[2000]; char buffer[1000], *miasma; char *next, *current; int len, i, ret; int host_socket; fd_set readmask; pid_t ident_pid; printf("*** ArIdent Daemon Version 2.0.2\n*** Forking...\n"); /* not even think in turning this into a switch. Been there, done that. */ ret = (int) fork(); if (ret == -1) { exit(1); } if (ret != 0) { _exit(0); } setsid(); if (argc) { /* make it look pwetty */ sprintf(argv[0], "[ArIdent Daemon for %s]", TALKERNAME); } host_socket = socket_connect(SERVER, HOSTPORT); if (host_socket < 0) { printf("Error in socket_connect() to %s:%s.\n", SERVER, HOSTPORT); exit(0); } authenticate_host(host_socket); ident_pid = getpid(); printf("*** Booted successfully with PID %d ***\n", ident_pid); for (;;) { FD_ZERO(&readmask); FD_SET(host_socket, &readmask); len = select(1 + host_socket, &readmask, NULL, NULL, NULL); if (len == -1) { continue; } len = recv(host_socket, inpstr, (sizeof inpstr) - 3, 0); if (!len) { #ifdef DEBUG printf("Disconnected from host.\n"); #endif shutdown(host_socket, SHUT_WR); close(host_socket); host_socket = -1; do { sleep(5); host_socket = socket_connect(SERVER, HOSTPORT); } while (host_socket < 0); authenticate_host(host_socket); continue; } inpstr[len] = '\0'; inpstr[len + 1] = 127; #ifdef DEBUG printf("RECEIVED: %s\n", inpstr); #endif next = inpstr - 1; while (*(++next) != 127) { current = next; while (*next && *next != '\n') { ++next; } *next = '\0'; if (!strncmp(current, "EXIT", 4)) { shutdown(host_socket, SHUT_WR); close(host_socket); exit(0); } switch (double_fork()) { case -1: exit(1); /* fork failure */ case 0: break; /* child continues */ default: continue; /* parent carries on the fine family tradition */ } if (argc) { sprintf(argv[0], "[ArIdent Child for %s]", TALKERNAME); } if (!strncmp(current, "PID", 3)) { sprintf(buffer, "PRETURN: %u\n", ident_pid); #ifdef DEBUG printf("[PID] %s\n", buffer); #endif send(host_socket, buffer, strlen(buffer), 0); _exit(0); } if (!strncmp(current, "SITE:", 5)) { /* They want a site. So call the site function and send a message back. */ miasma = current + 6; sprintf(buffer, "RETURN: %s %s\n", miasma, get_proc(miasma)); #ifdef DEBUG printf("[SITE] %s\n", buffer); #endif send(host_socket, buffer, strlen(buffer), 0); _exit(0); } if (!strncmp(current, "AUTH:", 5)) { char word[MAX_WORDS + 1][WORD_LEN + 1]; struct timeval t_struct; int auth_socket; /* They want a username. So setup nice sockets stuff. */ miasma = current + 6; wordfind(miasma, word); miasma = strchr(word[3], '!'); if (miasma) { *miasma = '\0'; } auth_socket = socket_connect(word[3], "113"); if (auth_socket < 0) { _exit(0); } sprintf(buffer, "%s, %s\n", word[1], word[2]); send(auth_socket, buffer, strlen(buffer), 0); for (;;) { FD_ZERO(&readmask); FD_SET(auth_socket, &readmask); t_struct.tv_sec = 10; t_struct.tv_usec = 0; len = select(1 + auth_socket, &readmask, NULL, NULL, &t_struct); if (len == -1) { continue; } if (!len) { shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } len = recv(auth_socket, authstr, (sizeof authstr) - 3, 0); if (!len) { shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } if (len > 255 || len < 5) { shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } authstr[len] = '\0'; /* Find the last "word" in inpstr. */ if (strstr(authstr, "ERROR")) { shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } for (i = len - 1; i > 2; --i) { if (authstr[i] == ' ' || authstr[i] == ':') { miasma = authstr + i + 1; sprintf(buffer, "ARETURN: %s %s %s\n", word[1], word[0], miasma); #ifdef DEBUG printf("[AUTH] %s\n", buffer); #endif send(host_socket, buffer, strlen(buffer), 0); shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } } shutdown(auth_socket, SHUT_WR); close(auth_socket); _exit(0); } } _exit(0); } } return 0; }
int main(int argc, char ** argv) { int fdm, fds, status; char *slavename; pid_t pid; test_init(argc, argv); fdm = open("/dev/ptmx", O_RDWR); if (fdm == -1) { err("Can't open a master pseudoterminal"); return 1; } grantpt(fdm); unlockpt(fdm); slavename = ptsname(fdm); pid = test_fork(); if (pid < 0) { err("fork() failed"); return 1; } if (pid == 0) { close(fdm); signal(SIGHUP, sighup_handler); if (setsid() == -1) return 1; /* set up a controlling terminal */ fds = open(slavename, O_RDWR); if (fds == -1) { err("Can't open a slave pseudoterminal %s", slavename); return 1; } if (ioctl(fdm, TIOCSCTTY, 1) < 0) { err("Can't setup a controlling terminal"); return 1; } close(fds); test_waitsig(); if (sighup) return 0; return 1; } test_daemon(); test_waitsig(); close(fdm); if (kill(pid, SIGTERM) == -1) { err("kill failed"); return 1; } pid = waitpid(pid, &status, 0); if (pid < 0) return 1; if (WIFEXITED(status)) { if (WEXITSTATUS(status)) { fail("The child returned %d", WEXITSTATUS(status)); return 1; } } else err("The child has been killed by %d", WTERMSIG(status)); pass(); return 0; }
int main(int argc, char *argv[]) { int ret, i, action = -1; char config_file[PATH_MAX] = {}; int type = 0; struct utsname u; int version, major, minor; /* Check kernel version: it must be >= 2.6.18 */ if (uname(&u) == -1) { fprintf(stderr, "Can't retrieve kernel version via uname()\n"); exit(EXIT_FAILURE); } sscanf(u.release, "%d.%d.%d", &version, &major, &minor); if (version < 2 && major < 6 && minor < 18) { fprintf(stderr, "Linux kernel version must be >= 2.6.18\n"); exit(EXIT_FAILURE); } for (i=1; i<argc; i++) { switch(argv[i][1]) { case 'd': set_operation_mode(&type, DAEMON, argv); break; case 'c': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_COMMIT, EXP_COMMIT, ALL_COMMIT, &action); break; case 'i': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_DUMP_INTERNAL, EXP_DUMP_INTERNAL, CT_DUMP_INTERNAL, &action); break; case 'e': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_DUMP_EXTERNAL, EXP_DUMP_EXTERNAL, CT_DUMP_EXTERNAL, &action); break; case 'C': if (++i < argc) { strncpy(config_file, argv[i], PATH_MAX); if (strlen(argv[i]) >= PATH_MAX){ config_file[PATH_MAX-1]='\0'; fprintf(stderr, "Path to config file " "to long. Cutting it " "down to %d characters", PATH_MAX); } break; } show_usage(argv[0]); fprintf(stderr, "Missing config filename\n"); break; case 'F': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_FLUSH_MASTER, EXP_FLUSH_MASTER, ALL_FLUSH_MASTER, &action); break; case 'f': set_operation_mode(&type, REQUEST, argv); if (i+1 < argc && argv[i+1][0] != '-') { if (strncmp(argv[i+1], "internal", strlen(argv[i+1])) == 0) { action = CT_FLUSH_INT_CACHE; i++; } else if (strncmp(argv[i+1], "external", strlen(argv[i+1])) == 0) { action = CT_FLUSH_EXT_CACHE; i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " "option `-f'\n", argv[i+1]); exit(EXIT_FAILURE); } } else { /* default to general flushing */ action = ALL_FLUSH_CACHE; } break; case 'R': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_RESYNC_MASTER, EXP_RESYNC_MASTER, ALL_RESYNC_MASTER, &action); break; case 'B': set_operation_mode(&type, REQUEST, argv); action = SEND_BULK; break; case 't': set_operation_mode(&type, REQUEST, argv); action = RESET_TIMERS; break; case 'k': set_operation_mode(&type, REQUEST, argv); action = KILL; break; case 's': set_operation_mode(&type, REQUEST, argv); /* we've got a parameter */ if (i+1 < argc && argv[i+1][0] != '-') { if (strncmp(argv[i+1], "network", strlen(argv[i+1])) == 0) { action = STATS_NETWORK; i++; } else if (strncmp(argv[i+1], "cache", strlen(argv[i+1])) == 0) { action = STATS_CACHE; i++; } else if (strncmp(argv[i+1], "runtime", strlen(argv[i+1])) == 0) { action = STATS_RUNTIME; i++; } else if (strncmp(argv[i+1], "multicast", strlen(argv[i+1])) == 0) { fprintf(stderr, "WARNING: use `link' " "instead of `multicast' as " "parameter.\n"); action = STATS_LINK; i++; } else if (strncmp(argv[i+1], "link", strlen(argv[i+1])) == 0) { action = STATS_LINK; i++; } else if (strncmp(argv[i+1], "rsqueue", strlen(argv[i+1])) == 0) { action = STATS_RSQUEUE; i++; } else if (strncmp(argv[i+1], "process", strlen(argv[i+1])) == 0) { action = STATS_PROCESS; i++; } else if (strncmp(argv[i+1], "queue", strlen(argv[i+1])) == 0) { action = STATS_QUEUE; i++; } else if (strncmp(argv[i+1], "ct", strlen(argv[i+1])) == 0) { action = STATS; i++; } else if (strncmp(argv[i+1], "expect", strlen(argv[i+1])) == 0) { action = EXP_STATS; i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " "option `-s'\n", argv[i+1]); exit(EXIT_FAILURE); } } else { /* default to general statistics */ action = STATS; } break; case 'S': fprintf(stderr, "WARNING: -S option is obsolete. " "Ignoring.\n"); break; case 'n': set_operation_mode(&type, REQUEST, argv); action = REQUEST_DUMP; break; case 'x': if (action == CT_DUMP_INTERNAL) action = CT_DUMP_INT_XML; else if (action == CT_DUMP_EXTERNAL) action = CT_DUMP_EXT_XML; else { show_usage(argv[0]); fprintf(stderr, "Error: Invalid parameters\n"); exit(EXIT_FAILURE); } break; case 'v': show_version(); exit(EXIT_SUCCESS); case 'h': show_usage(argv[0]); exit(EXIT_SUCCESS); default: show_usage(argv[0]); fprintf(stderr, "Unknown option: %s\n", argv[i]); return 0; break; } } if (!config_file[0]) strcpy(config_file, DEFAULT_CONFIGFILE); umask(0177); if ((ret = init_config(config_file)) == -1) { fprintf(stderr, "can't open config file `%s'\n", config_file); exit(EXIT_FAILURE); } if (type == REQUEST) { if (do_local_request(action, &conf.local, local_step) == -1) { fprintf(stderr, "can't connect: is conntrackd " "running? appropriate permissions?\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } /* * Setting up logging */ if (init_log() == -1) exit(EXIT_FAILURE); /* * lock file */ ret = open(CONFIG(lockfile), O_CREAT | O_EXCL | O_TRUNC, 0600); if (ret == -1) { fprintf(stderr, "lockfile `%s' exists, perhaps conntrackd " "already running?\n", CONFIG(lockfile)); exit(EXIT_FAILURE); } close(ret); /* * Setting process priority and scheduler */ nice(CONFIG(nice)); if (CONFIG(sched).type != SCHED_OTHER) { struct sched_param schedparam = { .sched_priority = CONFIG(sched).prio, }; ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam); if (ret == -1) { perror("sched"); exit(EXIT_FAILURE); } } /* * initialization process */ if (init() == -1) { close_log(); fprintf(stderr, "ERROR: conntrackd cannot start, please " "check the logfile for more info\n"); unlink(CONFIG(lockfile)); exit(EXIT_FAILURE); } chdir("/"); close(STDIN_FILENO); /* Daemonize conntrackd */ if (type == DAEMON) { pid_t pid; if ((pid = fork()) == -1) { perror("fork has failed: "); exit(EXIT_FAILURE); } else if (pid) exit(EXIT_SUCCESS); setsid(); close(STDOUT_FILENO); close(STDERR_FILENO); dlog(LOG_NOTICE, "-- starting in daemon mode --"); } else dlog(LOG_NOTICE, "-- starting in console mode --"); /* * run main process */ run(); return 0; }
/********************************************************************** *%FUNCTION: main *%ARGUMENTS: * argc, argv -- usual suspects *%RETURNS: * EXIT_SUCCESS or EXIT_FAILURE *%DESCRIPTION: * Main program. Options: * -C ifname -- Use interface for PPPoE clients * -S ifname -- Use interface for PPPoE servers * -B ifname -- Use interface for both clients and servers * -n sessions -- Maximum of "n" sessions ***********************************************************************/ int main(int argc, char *argv[]) { int opt; int nsess = DEFAULT_SESSIONS; struct sigaction sa; int beDaemon = 1; if (getuid() != geteuid() || getgid() != getegid()) { fprintf(stderr, "SECURITY WARNING: pppoe-relay will NOT run suid or sgid. Fix your installation.\n"); exit(1); } openlog("pppoe-relay", LOG_PID, LOG_DAEMON); while((opt = getopt(argc, argv, "hC:S:B:n:i:F")) != -1) { switch(opt) { case 'h': usage(argv[0]); break; case 'F': beDaemon = 0; break; case 'C': addInterface(optarg, 1, 0); break; case 'S': addInterface(optarg, 0, 1); break; case 'B': addInterface(optarg, 1, 1); break; case 'i': if (sscanf(optarg, "%u", &IdleTimeout) != 1) { fprintf(stderr, "Illegal argument to -i: should be -i timeout\n"); exit(EXIT_FAILURE); } CleanPeriod = IdleTimeout / TIMEOUT_DIVISOR; if (CleanPeriod < MIN_CLEAN_PERIOD) CleanPeriod = MIN_CLEAN_PERIOD; break; case 'n': if (sscanf(optarg, "%d", &nsess) != 1) { fprintf(stderr, "Illegal argument to -n: should be -n #sessions\n"); exit(EXIT_FAILURE); } if (nsess < 1 || nsess > 65534) { fprintf(stderr, "Illegal argument to -n: must range from 1 to 65534\n"); exit(EXIT_FAILURE); } break; default: usage(argv[0]); } } #ifdef USE_LINUX_PACKET #ifndef HAVE_STRUCT_SOCKADDR_LL fprintf(stderr, "The PPPoE relay does not work on Linux 2.0 kernels.\n"); exit(EXIT_FAILURE); #endif #endif /* Check that at least two interfaces were defined */ if (NumInterfaces < 2) { fprintf(stderr, "%s: Must define at least two interfaces\n", argv[0]); exit(EXIT_FAILURE); } /* Make a pipe for the cleaner */ if (pipe(CleanPipe) < 0) { fatalSys("pipe"); } /* Set up alarm handler */ sa.sa_handler = alarmHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGALRM, &sa, NULL) < 0) { fatalSys("sigaction"); } /* Allocate memory for sessions, etc. */ initRelay(nsess); /* Daemonize -- UNIX Network Programming, Vol. 1, Stevens */ if (beDaemon) { int i; i = fork(); if (i < 0) { fatalSys("fork"); } else if (i != 0) { /* parent */ exit(0); } setsid(); signal(SIGHUP, SIG_IGN); i = fork(); if (i < 0) { fatalSys("fork"); } else if (i != 0) { exit(0); } chdir("/"); closelog(); for (i=0; i<CLOSEFD; i++) { if (!keepDescriptor(i)) { close(i); } } /* We nuked our syslog descriptor... */ openlog("pppoe-relay", LOG_PID, LOG_DAEMON); } /* Kick off SIGALRM if there is an idle timeout */ if (IdleTimeout) alarm(1); /* Enter the relay loop */ relayLoop(); /* Shouldn't ever get here... */ return EXIT_FAILURE; }
static void disconnect(int N) { setsid();}
int main(int argc, char *argv[]) { pid_t sid; char upgfile[512]; int tPid; struct stat stat_buf; int use_storage_firmware = 0; if(argc < 2) { print_usage_exit(1); } /* FIX ME !!! * If we need further parameters for this procedure, then we should use * opt parser and formal parameters. * */ if(argv[1][0] == '-') { switch(argv[1][1]) { case 'b': strcpy(upgfile, "/tmp/mnt/USB/firmware.bin"); if(stat(upgfile, &stat_buf)) { printf("There is no \"firmware.bin\" in USB or USB is not inserted\n"); print_usage_exit(1); } else { use_storage_firmware = 1; printf("Using \"firmware.bin\" in USB to upgrade.\n"); } strcpy(upgfile, "/usr/sbin/ezpup /tmp/mnt/USB/firmware.bin"); break; case 's': strcpy(upgfile, "/tmp/mnt/SD/firmware.bin"); if(stat(upgfile, &stat_buf)) { printf("There is no \"firmware.bin\" in SD card or SD card is inserted\n"); print_usage_exit(1); } else { use_storage_firmware = 2; printf("Using \"firmware.bin\" in SD card to upgrade.\n"); } strcpy(upgfile, "/usr/sbin/ezpup /tmp/mnt/SD/firmware.bin"); break; case 'a': strcpy(upgfile, "/tmp/mnt/SD/firmware.bin"); if(stat(upgfile, &stat_buf)) { printf("There is no \"firmware.bin\" in SD card or SD card is inserted\n"); strcpy(upgfile, "/tmp/mnt/USB/firmware.bin"); if(stat(upgfile, &stat_buf)) { printf("There is no \"firmware.bin\" in USB or USB is not inserted\n"); print_usage_exit(1); } else { use_storage_firmware = 1; printf("Using \"firmware.bin\" in USB to upgrade.\n"); strcpy(upgfile, "/usr/sbin/ezpup /tmp/mnt/USB/firmware.bin"); } } else { use_storage_firmware = 2; printf("Using \"firmware.bin\" in SD card to upgrade.\n"); strcpy(upgfile, "/usr/sbin/ezpup /tmp/mnt/SD/firmware.bin"); } break; case 'u': if(argc == 3) { snprintf(upgfile, sizeof(upgfile), "wget %s -O /tmp/firmware 2>&1 | cat > /tmp/fw_log.txt", argv[2]); system(upgfile); if(!check_wget_ok("/tmp/fw_log.txt")) { printf("Unable to get URL %s\n", argv[2]); print_usage_exit(1); } snprintf(upgfile, sizeof(upgfile), "/usr/sbin/ezpup /tmp/firmware"); printf("Get firmware from %s successfully, using /tmp/firmware to upgrade.\n", argv[2]); } else { print_usage_exit(1); } break; } } else { snprintf(upgfile, sizeof(upgfile), "/usr/sbin/ezpup %s", argv[1]); } tPid = fork(); if(tPid < 0) { reboot(RB_AUTOBOOT); exit(1); // Error on fork } else if(tPid > 0) { exit(0); } else { FILE *fp; sid = setsid(); if (sid < 0) exit(EXIT_FAILURE); #if defined(PLATFORM_AXA) system("/usr/sbin/ezp-i2c gauge host booting"); #endif system("/sbin/stop_services.sh"); system("/sbin/reserve_link.sh"); system(upgfile); system("/tmp/ezp-i2c gauge upgrade finish"); fp = fopen("/tmp/fw_incorrect", "r"); if(fp) { printf("Upgrade failed, firmware incorrect\n"); fclose(fp); } else { printf("Upgrade successfully\n"); fp = fopen("/tmp/fw_correct", "w+"); if(fp) { fprintf(fp, "success\n"); fclose(fp); } } sleep(5); reboot(RB_AUTOBOOT); } return 0; }
static int lock_and_daemon(bool daemonize, const char *base_dir) { int ret, devnull_fd = 0, status = 0; int pipefd[2]; ret = pipe(pipefd); if (ret < 0) panic("pipe() for passing exit status failed: %m"); if (daemonize) { switch (fork()) { case 0: break; case -1: panic("fork() failed during daemonize: %m"); break; default: ret = read(pipefd[0], &status, sizeof(status)); if (ret != sizeof(status)) panic("read exit status failed: %m"); exit(status); break; } if (setsid() == -1) { sd_err("becoming a leader of a new session failed: %m"); status = 1; goto end; } switch (fork()) { case 0: break; case -1: sd_err("fork() failed during daemonize: %m"); status = 1; goto end; default: exit(0); break; } if (chdir("/")) { sd_err("chdir to / failed: %m"); status = 1; goto end; } devnull_fd = open("/dev/null", O_RDWR); if (devnull_fd < 0) { sd_err("opening /dev/null failed: %m"); status = 1; goto end; } } ret = lock_base_dir(base_dir); if (ret < 0) { sd_err("locking directory: %s failed", base_dir); status = 1; goto end; } if (daemonize) { /* * now we can use base_dir/sheep.log for logging error messages, * we can close 0, 1, and 2 safely */ dup2(devnull_fd, 0); dup2(devnull_fd, 1); dup2(devnull_fd, 2); close(devnull_fd); } end: ret = write(pipefd[1], &status, sizeof(status)); if (ret != sizeof(status)) panic("writing exit status failed: %m"); return status; }
int main(void) { char buf[100]; int pid; int fd, fd2; int ret; int opt=WDIOS_ENABLECARD; struct timespec req, rem; if((pid = fork())){ /* parent */ if((fd2 = open(PID_FILE, O_CREAT|O_WRONLY|O_TRUNC)) < 0){ exit(-1); } sprintf(buf, "%d\n", pid); if(write(fd2, buf, strlen(buf)) != strlen(buf)){ close(fd2); exit(-1); } close(fd2); } else{ #if !defined(DEBUG) close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); #endif if(setsid() == -1){ exit(-1); } signal(SIGTERM, die); if((fd = open(WD_FILE, O_WRONLY)) == -1){ exit(1); } if(ioctl(fd, WDIOC_SETOPTIONS, &opt) == -1){ close(fd); exit(2); } forever=1; while(forever){ if(ioctl(fd, WDIOC_KEEPALIVE, 0) == -1){ close(fd); exit(3); } req.tv_sec = INTERVAL; req.tv_nsec = 0; for(;forever;){ ret = nanosleep(&req, &rem); if(!ret){ /* normal end */ break; } else if(errno != EINTR){ openlog("wd-keepalive", LOG_CONS|LOG_PID, LOG_USER); syslog(LOG_NOTICE, "%d: nanosleep() errno=%d\n", __LINE__, errno); closelog(); forever=0; break; } else{ /* ret == EINTR */ openlog("wd-keepalive", LOG_CONS|LOG_PID, LOG_USER); syslog(LOG_NOTICE, "%d: nanosleep() receive EINTR", __LINE__); closelog(); req.tv_sec = rem.tv_sec; req.tv_nsec = rem.tv_nsec; } } } opt = WDIOS_DISABLECARD; if(ioctl(fd, WDIOC_SETOPTIONS, &opt) == -1){ close(fd); exit(4); } close(fd); openlog("wd-keepalive", LOG_CONS|LOG_PID, LOG_USER); syslog(LOG_ERR, "%d: loop exit\n", __LINE__); closelog(); } return 0; }
int launch_server(int server_port) { #ifdef HAVE_WIN32_PROC /* we need to start the server in the background */ /* we create a PIPE that will be used to wait for the server's "OK" */ /* message since the pipe handles must be inheritable, we use a */ /* security attribute */ HANDLE pipe_read, pipe_write; HANDLE stdout_handle, stderr_handle; SECURITY_ATTRIBUTES sa; STARTUPINFO startup; PROCESS_INFORMATION pinfo; char program_path[ MAX_PATH ]; int ret; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* create pipe, and ensure its read handle isn't inheritable */ ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); if (!ret) { fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); return -1; } SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); /* Some programs want to launch an adb command and collect its output by * calling CreateProcess with inheritable stdout/stderr handles, then * using read() to get its output. When this happens, the stdout/stderr * handles passed to the adb client process will also be inheritable. * When starting the adb server here, care must be taken to reset them * to non-inheritable. * Otherwise, something bad happens: even if the adb command completes, * the calling process is stuck while read()-ing from the stdout/stderr * descriptors, because they're connected to corresponding handles in the * adb server process (even if the latter never uses/writes to them). */ stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE ); stderr_handle = GetStdHandle( STD_ERROR_HANDLE ); if (stdout_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 ); } if (stderr_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 ); } ZeroMemory( &startup, sizeof(startup) ); startup.cb = sizeof(startup); startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); startup.hStdOutput = pipe_write; startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); startup.dwFlags = STARTF_USESTDHANDLES; ZeroMemory( &pinfo, sizeof(pinfo) ); /* get path of current program */ GetModuleFileName( NULL, program_path, sizeof(program_path) ); ret = CreateProcess( program_path, /* program path */ "adb fork-server server", /* the fork-server argument will set the debug = 2 in the child */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ DETACHED_PROCESS, /* the new process doesn't have a console */ NULL, /* use parent's environment block */ NULL, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo ); CloseHandle( pipe_write ); if (!ret) { fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); CloseHandle( pipe_read ); return -1; } CloseHandle( pinfo.hProcess ); CloseHandle( pinfo.hThread ); /* wait for the "OK\n" message */ { char temp[3]; DWORD count; ret = ReadFile( pipe_read, temp, 3, &count, NULL ); CloseHandle( pipe_read ); if ( !ret ) { fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); return -1; } if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } } #elif defined(HAVE_FORKEXEC) char path[PATH_MAX]; int fd[2]; // set up a pipe so the child can tell us when it is ready. // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. if (pipe(fd)) { fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; if (pid == 0) { // child side of the fork // redirect stderr to the pipe // we use stderr instead of stdout due to stdout's buffering behavior. adb_close(fd[0]); dup2(fd[1], STDERR_FILENO); adb_close(fd[1]); char str_port[30]; snprintf(str_port, sizeof(str_port), "%d", server_port); // child process int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL); // this should not return fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); } else { // parent side of the fork char temp[3]; temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; // wait for the "OK\n" message adb_close(fd[1]); int ret = adb_read(fd[0], temp, 3); int saved_errno = errno; adb_close(fd[0]); if (ret < 0) { fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); return -1; } if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } setsid(); } #else #error "cannot implement background server start on this platform" #endif return 0; }
int main (void) { struct sigaction sa; int f, i, fd, status; pid_t pid;; umask (022); klogctl (6, NULL, 0); if ((getpid ()) != 1) { exit (1); } /* * Ignore all signals. */ for (f = 1; f <= NSIG; f++) signal (f, SIG_IGN); signal (SIGCHLD, SIG_DFL); signal (SIGUSR1, signal_handler); signal (SIGUSR2, signal_handler); /* Close whatever files are open, and reset the console. */ close (0); close (1); close (2); console_stty (); setsid (); /* * Set default PATH variable. */ setenv ("PATH", PATH_DEFAULT, 1 /* Overwrite */ ); /* * Initialize /var/run/utmp (only works if /var is on * root and mounted rw) */ if ((fd = open (UTMP_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644)) >= 0) close (fd); /* * Say hello to the world */ initlog ("Welcome to \033[34m LFS-Linux\033[0m"); sysinit (); initlog ("starting login ..."); start_login (); while (1) { pid = wait (&status); if (pid == login_pid) { start_login (); } } return (0); }
int main(int ac, char **av) { extern char *optarg; extern int optind; int opt, sock_in, sock_out, newsock, i, pid = 0, on = 1; socklen_t aux; int remote_major, remote_minor; int perm_denied = 0; int ret; fd_set fdset; #ifdef HAVE_IPV6_SMTH struct sockaddr_in6 sin; #else struct sockaddr_in sin; #endif char buf[100]; /* Must not be larger than remote_version. */ char remote_version[100]; /* Must be at least as big as buf. */ char addr[STRLEN]; char *comment; char *ssh_remote_version_string = NULL; FILE *f; #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) struct linger linger; #endif /* SO_LINGER */ int done; chdir(BBSHOME); /* Save argv[0]. */ saved_argv = av; if (strchr(av[0], '/')) av0 = strrchr(av[0], '/') + 1; else av0 = av[0]; /* Prevent core dumps to avoid revealing sensitive information. */ signals_prevent_core(); /* Set SIGPIPE to be ignored. */ signal(SIGPIPE, SIG_IGN); /* Initialize configuration options to their default values. */ initialize_server_options(&options); addr[0]=0; /* Parse command-line arguments. */ while ((opt = getopt(ac, av, "f:a:p:b:k:h:g:diqV:")) != EOF) { switch (opt) { case 'f': config_file_name = optarg; break; case 'd': debug_flag = 1; break; case 'i': inetd_flag = 1; break; case 'q': options.quiet_mode = 1; break; case 'b': options.server_key_bits = atoi(optarg); break; case 'a': if(optarg[0]) snprintf(addr,STRLEN,"%s",optarg); break; case 'p': if(isdigit(optarg[0])) options.port=atoi(optarg); break; case 'g': options.login_grace_time = atoi(optarg); break; case 'k': options.key_regeneration_time = atoi(optarg); break; case 'h': options.host_key_file = optarg; break; case 'V': ssh_remote_version_string = optarg; break; case '?': default: #ifdef F_SECURE_COMMERCIAL #endif /* F_SECURE_COMMERCIAL */ fprintf(stderr, "sshd version %s [%s]\n", SSH_VERSION, HOSTTYPE); fprintf(stderr, "Usage: %s [options]\n", av0); fprintf(stderr, "Options:\n"); fprintf(stderr, " -f file Configuration file (default %s/sshd_config)\n", ETCDIR); fprintf(stderr, " -d Debugging mode\n"); fprintf(stderr, " -i Started from inetd\n"); fprintf(stderr, " -q Quiet (no logging)\n"); fprintf(stderr, " -a addr Bind to the specified address (default: all)\n"); fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n"); fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); fprintf(stderr, " -h file File from which to read host key (default: %s)\n", HOST_KEY_FILE); fprintf(stderr, " -V str Remote version string already read from the socket\n"); exit(1); } } /* Read server configuration options from the configuration file. */ read_server_config(&options, config_file_name); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); /* Check certain values for sanity. */ if (options.server_key_bits < 512 || options.server_key_bits > 32768) { fprintf(stderr, "fatal: Bad server key size.\n"); exit(1); } if (options.port < 1 || options.port > 65535) { fprintf(stderr, "fatal: Bad port number.\n"); exit(1); } if (options.umask != -1) { umask(options.umask); } /* Check that there are no remaining arguments. */ if (optind < ac) { fprintf(stderr, "fatal: Extra argument %.100s.\n", av[optind]); exit(1); } /* Initialize the log (it is reinitialized below in case we forked). */ log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility); debug("sshd version %.100s [%.100s]", SSH_VERSION, HOSTTYPE); /* Load the host key. It must have empty passphrase. */ done = load_private_key(geteuid(), options.host_key_file, "", &sensitive_data.host_key, &comment); if (!done) { if (debug_flag) { fprintf(stderr, "Could not load host key: %.200s\n", options.host_key_file); fprintf(stderr, "fatal: Please check that you have sufficient permissions and the file exists.\n"); } else { log_init(av0, !inetd_flag, 1, 0, options.log_facility); error("fatal: Could not load host key: %.200s. Check path and permissions.", options.host_key_file); } exit(1); } xfree(comment); /* If not in debugging mode, and not started from inetd, disconnect from the controlling terminal, and fork. The original process exits. */ if (!debug_flag && !inetd_flag) #ifdef HAVE_DAEMON if (daemon(0, 0) < 0) error("daemon: %.100s", strerror(errno)); chdir(BBSHOME); #else /* HAVE_DAEMON */ { #ifdef TIOCNOTTY int fd; #endif /* TIOCNOTTY */ /* Fork, and have the parent exit. The child becomes the server. */ if (fork()) exit(0); /* Redirect stdin, stdout, and stderr to /dev/null. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); /* Disconnect from the controlling tty. */ #ifdef TIOCNOTTY fd = open("/dev/tty", O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ #ifdef HAVE_SETSID #ifdef ultrix setpgrp(0, 0); #else /* ultrix */ if (setsid() < 0) error("setsid: %.100s", strerror(errno)); #endif #endif /* HAVE_SETSID */ } #endif /* HAVE_DAEMON */ /* Reinitialize the log (because of the fork above). */ log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility); /* Check that server and host key lengths differ sufficiently. This is necessary to make double encryption work with rsaref. Oh, I hate software patents. */ if (options.server_key_bits > sensitive_data.host_key.bits - SSH_KEY_BITS_RESERVED && options.server_key_bits < sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED) { options.server_key_bits = sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED; debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits); } /* Initialize memory allocation so that any freed MP_INT data will be zeroed. */ rsa_set_mp_memory_allocation(); /* Do not display messages to stdout in RSA code. */ rsa_set_verbose(debug_flag); /* Initialize the random number generator. */ debug("Initializing random number generator; seed file %.200s", options.random_seed_file); random_initialize(&sensitive_data.random_state, geteuid(), options.random_seed_file); /* Chdir to the root directory so that the current disk can be unmounted if desired. */ idle_timeout = options.idle_timeout; /* Start listening for a socket, unless started from inetd. */ if (inetd_flag) { int s1, s2; s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ s2 = dup(s1); sock_in = dup(0); sock_out = dup(1); /* We intentionally do not close the descriptors 0, 1, and 2 as our code for setting the descriptors won\'t work if ttyfd happens to be one of those. */ debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); /* Generate an rsa key. */ log_msg("Generating %d bit RSA key.", options.server_key_bits); rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits); random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file); log_msg("RSA key generation complete."); } else { /* Create socket for listening. */ #ifdef HAVE_IPV6_SMTH listen_sock = socket(AF_INET6, SOCK_STREAM, 0); #else listen_sock = socket(AF_INET, SOCK_STREAM, 0); #endif if (listen_sock < 0) fatal("socket: %.100s", strerror(errno)); /* Set socket options. We try to make the port reusable and have it close as fast as possible without waiting in unnecessary wait states on close. */ setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) linger.l_onoff = 1; linger.l_linger = 15; setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); #endif /* SO_LINGER */ /* Initialize the socket address. */ memset(&sin, 0, sizeof(sin)); #ifdef HAVE_IPV6_SMTH sin.sin6_family = AF_INET6; if ( inet_pton(AF_INET6, addr, &(sin.sin6_addr)) <= 0 ) sin.sin6_addr = in6addr_any; sin.sin6_port = htons(options.port); #else sin.sin_family = AF_INET; if ( inet_pton(AF_INET, addr, &(sin.sin_addr)) <= 0 ) sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(options.port); #endif /* Bind the socket to the desired port. */ if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { error("bind: %.100s", strerror(errno)); shutdown(listen_sock, 2); close(listen_sock); fatal("Bind to port %d failed: %.200s.", options.port, strerror(errno)); } /* COMMAN : setuid to bbs */ if(setgid(BBSGID)==-1) exit(8); if(setuid(BBSUID)==-1) exit(8); #if 0 /* etnlegend, 2006.10.31 ... */ if (!debug_flag) { /* Record our pid in /etc/sshd_pid to make it easier to kill the correct sshd. We don\'t want to do this before the bind above because the bind will fail if there already is a daemon, and this will overwrite any old pid in the file. */ f = fopen(options.pid_file, "w"); if (f) { fprintf(f, "%u\n", (unsigned int) getpid()); fclose(f); } } #endif /* Start listening on the port. */ log_msg("Server listening on port %d.", options.port); if (listen(listen_sock, 5) < 0) fatal("listen: %.100s", strerror(errno)); /* Generate an rsa key. */ log_msg("Generating %d bit RSA key.", options.server_key_bits); rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits); random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file); log_msg("RSA key generation complete."); /* Schedule server key regeneration alarm. */ signal(SIGALRM, key_regeneration_alarm); alarm(options.key_regeneration_time); /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); /* AIX sends SIGDANGER when memory runs low. The default action is to terminate the process. This sometimes makes it difficult to log in and fix the problem. */ #ifdef SIGDANGER signal(SIGDANGER, sigdanger_handler); #endif /* SIGDANGER */ /* Arrange SIGCHLD to be caught. */ signal(SIGCHLD, main_sigchld_handler); if(!debug_flag){ if(!addr[0]) sprintf(buf,"var/sshbbsd.%d.pid",options.port); else sprintf(buf,"var/sshbbsd.%d_%s.pid",options.port,addr); if((f=fopen(buf,"w"))){ fprintf(f,"%d\n",(int)getpid()); fclose(f); } } /* Stay listening for connections until the system crashes or the daemon is killed with a signal. */ for (;;) { if (received_sighup) sighup_restart(); /* Wait in select until there is a connection. */ FD_ZERO(&fdset); FD_SET(listen_sock, &fdset); ret = select(listen_sock + 1, &fdset, NULL, NULL, NULL); if (ret < 0 || !FD_ISSET(listen_sock, &fdset)) { if (errno == EINTR) continue; error("select: %.100s", strerror(errno)); continue; } aux = sizeof(sin); newsock = accept(listen_sock, (struct sockaddr *) &sin, &aux); if (newsock < 0) { if (errno == EINTR) continue; error("accept: %.100s", strerror(errno)); continue; } /* Got connection. Fork a child to handle it, unless we are in debugging mode. */ if (debug_flag) { /* In debugging mode. Close the listening socket, and start processing the connection without forking. */ debug("Server will not fork when running in debugging mode."); close(listen_sock); sock_in = newsock; sock_out = newsock; pid = getpid(); #ifdef LIBWRAP { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL); fromhost(&req); if (!hosts_access(&req)) refuse(&req); syslog(allow_severity, "connect from %s", eval_client(&req)); } #endif /* LIBWRAP */ break; } else { #ifdef CHECK_IP_LINK #ifdef HAVE_IPV6_SMTH if (check_IP_lists(sin.sin6_addr)==0) #else if (check_IP_lists(sin.sin_addr.s_addr)==0) #endif #endif /* Normal production daemon. Fork, and have the child process the connection. The parent continues listening. */ if ((pid = fork()) == 0) { /* Child. Close the listening socket, and start using the accepted socket. Reinitialize logging (since our pid has changed). We break out of the loop to handle the connection. */ close(listen_sock); sock_in = newsock; sock_out = newsock; #ifdef LIBWRAP { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL); fromhost(&req); if (!hosts_access(&req)) refuse(&req); syslog(allow_severity, "connect from %s", eval_client(&req)); } #endif /* LIBWRAP */ log_init(av0, debug_flag && !inetd_flag, options.fascist_logging || debug_flag, options.quiet_mode, options.log_facility); break; } } /* Parent. Stay in the loop. */ if (pid < 0) error("fork: %.100s", strerror(errno)); else debug("Forked child %d.", pid); /* Mark that the key has been used (it was "given" to the child). */ key_used = 1; random_acquire_light_environmental_noise(&sensitive_data.random_state); /* Close the new socket (the child is now taking care of it). */ close(newsock); } } /* This is the child processing a new connection. */ /* Disable the key regeneration alarm. We will not regenerate the key since we are no longer in a position to give it to anyone. We will not restart on SIGHUP since it no longer makes sense. */ alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); /* Set socket options for the connection. We want the socket to close as fast as possible without waiting for anything. If the connection is not a socket, these will do nothing. */ /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) linger.l_onoff = 1; linger.l_linger = 15; setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); #endif /* SO_LINGER */ /* Register our connection. This turns encryption off because we do not have a key. */ packet_set_connection(sock_in, sock_out, &sensitive_data.random_state); /* Log the connection. */ log_msg("Connection from %.100s port %d", get_remote_ipaddr(), get_remote_port()); /* Check whether logins are denied from this host. */ { const char *hostname = get_canonical_hostname(); const char *ipaddr = get_remote_ipaddr(); int i; if (options.num_deny_hosts > 0) { for (i = 0; i < options.num_deny_hosts; i++) if (match_host(hostname, ipaddr, options.deny_hosts[i])) perm_denied = 1; } if ((!perm_denied) && options.num_allow_hosts > 0) { for (i = 0; i < options.num_allow_hosts; i++) if (match_host(hostname, ipaddr, options.allow_hosts[i])) break; if (i >= options.num_allow_hosts) perm_denied = 1; } if (perm_denied && options.silent_deny) { close(sock_in); close(sock_out); exit(0); } } /* We don't want to listen forever unless the other side successfully authenticates itself. So we set up an alarm which is cleared after successful authentication. A limit of zero indicates no limit. Note that we don't set the alarm in debugging mode; it is just annoying to have the server exit just when you are about to discover the bug. */ signal(SIGALRM, grace_alarm_handler); if (!debug_flag) alarm(options.login_grace_time); if (ssh_remote_version_string == NULL) { /* Send our protocol version identification. */ snprintf(buf, sizeof(buf), "SSH-%d.%d-%.50s", PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); strcat(buf, "\n"); if (write(sock_out, buf, strlen(buf)) != strlen(buf)) fatal_severity(SYSLOG_SEVERITY_INFO, "Could not write ident string."); } if (ssh_remote_version_string == NULL) { /* Read other side\'s version identification. */ for (i = 0; i < sizeof(buf) - 1; i++) { if (read(sock_in, &buf[i], 1) != 1) fatal_severity(SYSLOG_SEVERITY_INFO, "Did not receive ident string."); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; break; } if (buf[i] == '\n') { /* buf[i] == '\n' */ buf[i + 1] = 0; break; } } buf[sizeof(buf) - 1] = 0; } else { strncpy(buf, ssh_remote_version_string, sizeof(buf) - 1); buf[sizeof(buf) - 1] = 0; } /* Check that the versions match. In future this might accept several versions and set appropriate flags to handle them. */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) { const char *s = "Protocol mismatch.\n"; (void) write(sock_out, s, strlen(s)); close(sock_in); close(sock_out); fatal_severity(SYSLOG_SEVERITY_INFO, "Bad protocol version identification: %.100s", buf); } debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version); switch (check_emulation(remote_major, remote_minor, NULL, NULL)) { case EMULATE_MAJOR_VERSION_MISMATCH: { const char *s = "Protocol major versions differ.\n"; (void) write(sock_out, s, strlen(s)); close(sock_in); close(sock_out); fatal_severity(SYSLOG_SEVERITY_INFO, "Protocol major versions differ: %d vs. %d", PROTOCOL_MAJOR, remote_major); } break; case EMULATE_VERSION_TOO_OLD: packet_disconnect("Your ssh version is too old and is no " "longer supported. Please install a newer version."); break; case EMULATE_VERSION_NEWER: packet_disconnect("This server does not support your " "new ssh version."); break; case EMULATE_VERSION_OK: break; default: fatal("Unexpected return value from check_emulation."); } if (perm_denied) { const char *hostname = get_canonical_hostname(); log_msg("Connection from %.200s not allowed.\n", hostname); packet_disconnect("Sorry, you are not allowed to connect."); /*NOTREACHED*/} packet_set_nonblocking(); /* Handle the connection. We pass as argument whether the connection came from a privileged port. */ do_connection(get_remote_port() < 1024); /* The connection has been terminated. */ log_msg("Closing connection to %.100s", get_remote_ipaddr()); packet_close(); exit(0); }
int start_stop_daemon_main(int argc, char **argv) { unsigned long opt; char *signame = NULL; char *startas = NULL; bb_applet_long_options = ssd_long_options; bb_opt_complementaly = "K~S:S~K"; opt = bb_getopt_ulflags(argc, argv, "KSbqma:n:s:u:x:p:", &startas, &cmdname, &signame, &userspec, &execname, &pidfile); /* Check one and only one context option was given */ if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) { bb_show_usage(); } if (signame) { signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); } if (!execname && !pidfile && !userspec && !cmdname) bb_error_msg_and_die ("need at least one of -x, -p, -u, or -n"); if (!startas) startas = execname; if ((opt & SSD_CTX_START) && !startas) bb_error_msg_and_die ("-S needs -x or -a"); if ((opt & SSD_OPT_MAKEPID) && pidfile == NULL) bb_error_msg_and_die ("-m needs -p"); argc -= optind; argv += optind; if (userspec && sscanf(userspec, "%d", &user_id) != 1) user_id = my_getpwnam(userspec); if (opt & SSD_CTX_STOP) { do_stop(); return EXIT_SUCCESS; } do_procinit(); if (found) { if (!quiet) printf("%s already running.\n%d\n", execname ,found->pid); return EXIT_SUCCESS; } *--argv = startas; if (opt & SSD_OPT_BACKGROUND) { if (daemon(0, 0) == -1) bb_perror_msg_and_die ("unable to fork"); setsid(); } if (opt & SSD_OPT_MAKEPID) { /* user wants _us_ to make the pidfile */ FILE *pidf = fopen(pidfile, "w"); pid_t pidt = getpid(); if (pidf == NULL) bb_perror_msg_and_die("Unable to write pidfile '%s'", pidfile); fprintf(pidf, "%d\n", pidt); fclose(pidf); } execv(startas, argv); bb_perror_msg_and_die ("unable to start %s", startas); }
////////////////////////////////////////////////////////////////////////////// // // Start // bool AppInit(int argc, char* argv[]) { boost::thread_group threadGroup; boost::thread* detectShutdownThread = NULL; bool fRet = false; try { // // Parameters // // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() ParseParameters(argc, argv); if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); return false; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch(std::exception &e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; } // Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause) if (!SelectParamsFromCommandLine()) { fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); return false; } if (mapArgs.count("-?") || mapArgs.count("--help")) { // First part of help message is specific to bitcoind / RPC client std::string strUsage = _("Reddcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n\n" + _("Usage:") + "\n" + " reddcoind [options] " + _("Start Reddcoin Core Daemon") + "\n" + _("Usage (deprecated, use reddcoin-cli):") + "\n" + " reddcoind [options] <command> [params] " + _("Send command to Reddcoin Core") + "\n" + " reddcoind [options] help " + _("List commands") + "\n" + " reddcoind [options] help <command> " + _("Get help for a command") + "\n"; strUsage += "\n" + HelpMessage(HMM_BITCOIND); strUsage += "\n" + HelpMessageCli(false); fprintf(stdout, "%s", strUsage.c_str()); return false; } // Command-line RPC bool fCommandLine = false; for (int i = 1; i < argc; i++) if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:")) fCommandLine = true; if (fCommandLine) { int ret = CommandLineRPC(argc, argv); exit(ret); } #ifndef WIN32 fDaemon = GetBoolArg("-daemon", false); if (fDaemon) { fprintf(stdout, "Bitcoin server starting\n"); // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) // Parent process, pid is child process id { CreatePidFile(GetPidFile(), pid); return true; } // Child process falls through to rest of initialization pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif SoftSetBoolArg("-server", true); detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); fRet = AppInit2(threadGroup); } catch (std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { PrintExceptionContinue(NULL, "AppInit()"); } if (!fRet) { if (detectShutdownThread) detectShutdownThread->interrupt(); threadGroup.interrupt_all(); // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // the startup-failure cases to make sure they don't result in a hang due to some // thread-blocking-waiting-for-another-thread-during-startup case } if (detectShutdownThread) { detectShutdownThread->join(); delete detectShutdownThread; detectShutdownThread = NULL; } Shutdown(); return fRet; }
static ATTRIBUTE_NO_SANITIZE_THREAD void backtrace_sigaction(int signum, siginfo_t *info, void* ptr) { void *array[42]; size_t size; void * caller_address; ucontext_t *uc = (ucontext_t *) ptr; int gdb_pid = -1; /* get all entries on the stack */ size = backtrace(array, 42); /* Get the address at the time the signal was raised */ #if defined(REG_RIP) caller_address = (void *) uc->uc_mcontext.gregs[REG_RIP]; #elif defined(REG_EIP) caller_address = (void *) uc->uc_mcontext.gregs[REG_EIP]; #elif defined(__arm__) caller_address = (void *) uc->uc_mcontext.arm_pc; #elif defined(__mips__) caller_address = (void *) uc->uc_mcontext.sc_pc; #elif defined(REG_PC) && defined(__e2k__) caller_address = (void *) ((mcontext_t*) &uc->uc_mcontext)->mc_gregs[REG_PC]; #else /* TODO support more arch(s) */ # warning Unsupported architecture. caller_address = info->si_addr; #endif int should_die = 0; switch(info->si_signo) { case SIGXCPU: case SIGXFSZ: should_die = 1; break; case SIGABRT: case SIGALRM: if (info->si_pid == getpid()) should_die = 1; case SIGBUS: case SIGFPE: case SIGILL: case SIGSEGV: #ifndef SI_FROMKERNEL # define SI_FROMKERNEL(info) (info->si_code > 0) #endif if (SI_FROMKERNEL(info)) should_die = 1; } char time_buf[64]; time_t t = ldap_time_unsteady(); strftime(time_buf, sizeof(time_buf), "%F-%H%M%S", localtime(&t)); char name_buf[PATH_MAX]; int fd = -1; #ifdef snprintf # undef snprintf #endif if (snprintf(name_buf, sizeof(name_buf), "%s/slapd-backtrace.%s-%i.log%c", backtrace_homedir ? backtrace_homedir : ".", time_buf, getpid(), 0) > 0) fd = open(name_buf, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 0644); if (fd < 0) { if (backtrace_homedir) fd = open(strrchr(name_buf, '/') + 1, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 0644); if (fd < 0) fd = STDERR_FILENO; dprintf(fd, "\n\n*** Unable create \"%s\": %s!", name_buf, STRERROR(errno)); } dprintf(fd, "\n\n*** Signal %d (%s), address is %p from %p\n", signum, strsignal(signum), info->si_addr, (void *)caller_address); int n = readlink("/proc/self/exe", name_buf, sizeof(name_buf) - 1); if (n > 0) { name_buf[n] = 0; dprintf(fd, " Executable file %s\n", name_buf); } else { dprintf(fd, " Unable read executable name: %s\n", STRERROR(errno)); strcpy(name_buf, "unknown"); } void** actual = array; int frame = 0; for (n = 0; n < size; ++n) if (array[n] == caller_address) { frame = n; actual = array + frame; size -= frame; break; } dprintf(fd, "\n*** Backtrace by glibc:\n"); backtrace_symbols_fd(actual, size, fd); int mem_map_fd = open("/proc/self/smaps", O_RDONLY, 0); if (mem_map_fd >= 0) { char buf[1024]; dprintf(fd, "\n*** Memory usage map (by /proc/self/smaps):\n"); while(1) { int n = read(mem_map_fd, &buf, sizeof(buf)); if (n < 1) break; if (write(fd, &buf, n) != n) break; } close(mem_map_fd); } /* avoid ECHILD from waitpid() */ signal(SIGCHLD, SIG_DFL); dprintf(fd, "\n*** Backtrace by addr2line:\n"); for(n = 0; n < size; ++n) { int status = EXIT_FAILURE, child_pid = fork(); if (! child_pid) { char addr_buf[64]; close(STDIN_FILENO); dup2(fd, STDOUT_FILENO); close(fd); dprintf(STDOUT_FILENO, "(%d) %p: ", n, actual[n]); sprintf(addr_buf, "%p", actual[n]); execlp("addr2line", "addr2line", addr_buf, "-C", "-f", "-i", #if __GLIBC_PREREQ(2,14) "-p", /* LY: not available on RHEL6, guest by glibc version */ #endif "-e", name_buf, NULL); exit(EXIT_FAILURE); } else if (child_pid < 0) { dprintf(fd, "\n*** Unable complete backtrace by addr2line, sorry (%s, %d).\n", "fork", errno); break; } else if (waitpid(child_pid, &status, 0) < 0 || status != W_EXITCODE(EXIT_SUCCESS, 0)) { dprintf(fd, "\n*** Unable complete backtrace by addr2line, sorry (%s, pid %d, errno %d, status 0x%x).\n", "waitpid", child_pid, errno, status); break; } } if (is_debugger_present()) { dprintf(fd, "*** debugger already present\n"); goto ballout; } int retry_by_return = 0; if (should_die && SI_FROMKERNEL(info)) { /* LY: Expect kernel kill us again, * therefore for switch to 'guilty' thread and we may just return, * instead of sending SIGTRAP and later switch stack frame by GDB. */ retry_by_return = 1; } if (is_valgrind_present()) { dprintf(fd, "*** valgrind present, skip backtrace by gdb\n"); goto ballout; } int pipe_fd[2]; if (pipe(pipe_fd)) { pipe_fd[0] = pipe_fd[1] = -1; goto ballout; } gdb_is_ready_for_backtrace = 0; pid_t tid = syscall(SYS_gettid); gdb_pid = fork(); if (!gdb_pid) { char pid_buf[16]; sprintf(pid_buf, "%d", getppid()); dup2(pipe_fd[0], STDIN_FILENO); close(pipe_fd[1]); pipe_fd[0] = pipe_fd[1] =-1; dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); for(fd = getdtablesize(); fd > STDERR_FILENO; --fd) close(fd); setsid(); setpgid(0, 0); dprintf(STDOUT_FILENO, "\n*** Backtrace by GDB " #if GDB_SWITCH2GUILTY_THREAD "(pid %s, LWP %i, frame #%d):\n", pid_buf, tid, frame); #else "(pid %s, LWP %i, please find frame manually):\n", pid_buf, tid); #endif execlp("gdb", "gdb", "-q", "-se", name_buf, "-n", NULL); kill(getppid(), SIGKILL); dprintf(STDOUT_FILENO, "\n*** Sorry, GDB launch failed: %s\n", STRERROR(errno)); fsync(STDOUT_FILENO); exit(EXIT_FAILURE); }
/** * Does the chdir, fork, setsid, etc. to become a daemon process. * * @param pidfile #NULL, or pidfile to create * @param print_pid_pipe pipe to print daemon's pid to, or -1 for none * @param error return location for errors * @param keep_umask #TRUE to keep the original umask * @returns #FALSE on failure */ dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, DBusError *error, dbus_bool_t keep_umask) { const char *s; pid_t child_pid; int dev_null_fd; _dbus_verbose ("Becoming a daemon...\n"); _dbus_verbose ("chdir to /\n"); if (chdir ("/") < 0) { dbus_set_error (error, DBUS_ERROR_FAILED, "Could not chdir() to root directory"); return FALSE; } _dbus_verbose ("forking...\n"); switch ((child_pid = fork ())) { case -1: _dbus_verbose ("fork failed\n"); dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to fork daemon: %s", _dbus_strerror (errno)); return FALSE; break; case 0: _dbus_verbose ("in child, closing std file descriptors\n"); /* silently ignore failures here, if someone * doesn't have /dev/null we may as well try * to continue anyhow */ dev_null_fd = open ("/dev/null", O_RDWR); if (dev_null_fd >= 0) { dup2 (dev_null_fd, 0); dup2 (dev_null_fd, 1); s = _dbus_getenv ("DBUS_DEBUG_OUTPUT"); if (s == NULL || *s == '\0') dup2 (dev_null_fd, 2); else _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n"); } if (!keep_umask) { /* Get a predictable umask */ _dbus_verbose ("setting umask\n"); umask (022); } _dbus_verbose ("calling setsid()\n"); if (setsid () == -1) _dbus_assert_not_reached ("setsid() failed"); break; default: if (!_dbus_write_pid_to_file_and_pipe (pidfile, print_pid_pipe, child_pid, error)) { _dbus_verbose ("pid file or pipe write failed: %s\n", error->message); kill (child_pid, SIGTERM); return FALSE; } _dbus_verbose ("parent exiting\n"); _exit (0); break; } return TRUE; }
////////////////////////////////////////////////////////////////////////////// // // Start // bool AppInit(int argc, char* argv[]) { boost::thread_group threadGroup; bool fRet = false; try { // // Parameters // // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() ParseParameters(argc, argv); if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified directory does not exist\n"); Shutdown(); } ReadConfigFile(mapArgs, mapMultiArgs); if (mapArgs.count("-?") || mapArgs.count("--help")) { // First part of help message is specific to bitcoind / RPC client std::string strUsage = _("Espers version") + " " + FormatFullVersion() + "\n\n" + _("Usage:") + "\n" + " Espersd [options] " + "\n" + " Espersd [options] <command> [params] " + _("Send command to -server or Espersd") + "\n" + " Espersd [options] help " + _("List commands") + "\n" + " Espersd [options] help <command> " + _("Get help for a command") + "\n"; strUsage += "\n" + HelpMessage(); fprintf(stdout, "%s", strUsage.c_str()); return false; } // Command-line RPC for (int i = 1; i < argc; i++) if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "Espers:")) fCommandLine = true; if (fCommandLine) { if (!SelectParamsFromCommandLine()) { fprintf(stderr, "Error: invalid combination of -regtest and -testnet.\n"); return false; } int ret = CommandLineRPC(argc, argv); exit(ret); } #if !defined(WIN32) fDaemon = GetBoolArg("-daemon", false); if (fDaemon) { // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) // Parent process, pid is child process id { CreatePidFile(GetPidFile(), pid); return true; } // Child process falls through to rest of initialization pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif fRet = AppInit2(threadGroup); } catch (std::exception& e) { PrintException(&e, "AppInit()"); } catch (...) { PrintException(NULL, "AppInit()"); } if (!fRet) { threadGroup.interrupt_all(); // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // the startup-failure cases to make sure they don't result in a hang due to some // thread-blocking-waiting-for-another-thread-during-startup case } else { WaitForShutdown(&threadGroup); } Shutdown(); return fRet; }
bool cOpenHpiDaemon::Initialize() { if ( m_daemon ) { DbgInit( "become a daemon.\n" ); pid_t pid = fork(); if ( pid < 0 ) { fprintf( stderr, "cannot fork: %s !\n", strerror( errno ) ); return false; } // parent process if ( pid != 0 ) exit( 0 ); // become the session leader setsid(); // second fork to become a real daemon pid = fork(); if ( pid < 0 ) { fprintf( stderr, "cannot fork: %s !\n", strerror( errno ) ); return false; } // parent process if ( pid != 0 ) exit( 0 ); chdir( "/" ); umask( 0 ); } // use config file given by the command line if ( m_config ) setenv( "OPENHPI_CONF", m_config, 1 ); // initialize openhpi DbgInit( "initialize openhpi.\n" ); SaErrorT rv = saHpiInitialize( &m_version ); if ( rv != SA_OK ) { fprintf( stderr, "cannot initialize openhpi: %s !\n", decode_error( rv ) ); return false; } // create a session rv = saHpiSessionOpen( SAHPI_DEFAULT_DOMAIN_ID, &m_session, 0 ); if ( rv != SA_OK ) { fprintf( stderr, "cannot create session: %s !\n", decode_error( rv ) ); saHpiFinalize(); return false; } // subscribe rv = saHpiSubscribe( m_session, SAHPI_TRUE ); if ( rv != SA_OK ) { fprintf( stderr, "cannot subscribe: %s !\n", decode_error( rv ) ); saHpiSessionClose( m_session ); saHpiFinalize(); return false; } // open daemon socket DbgInit( "create daemon connection port %d.\n", m_daemon_port ); m_main_socket = ServerConnectionMainOpen( m_daemon_port ); if ( !m_main_socket ) { fprintf( stderr, "cannot create daemon socket: %d, %s !\n", errno, strerror( errno ) ); saHpiUnsubscribe( m_session ); saHpiSessionClose( m_session ); saHpiFinalize(); return false; } if ( m_interactive ) DbgInit( "interactive\n" ); DbgInit( "daemon is up.\n" ); return true; }
int main(int argc, char *argv[]) { int longindex; int optchar; String p; KeyEntryPtr_t e; zoneMapPtr_t zm; /* Set the program name */ progName=argv[0]; /* Parse the arguments. */ while((optchar=getopt_long(argc, argv, SHORT_OPTIONS, longOptions, &longindex)) != EOF) { /* Handle each argument. */ switch(optchar) { /* Was it a long option? */ case 0: /* Hrmm, something we don't know about? */ fatal("Unhandled long getopt option '%s'", longOptions[longindex].name); /* If it was an error, exit right here. */ case '?': exit(1); /* Was it a config file path ? */ case 'c': confreadStringCopy(configFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New config file path is: %s", configFile); break; /* Was it a debug level set? */ case 'd': /* Save the value. */ debugLvl=atoi(optarg); if(debugLvl < 0 || debugLvl > DEBUG_MAX) { fatal("Invalid debug level"); } break; /* Was it a pid file switch? */ case 'f': confreadStringCopy(pidFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New pid file path is: %s", pidFile); configOverride |= CO_PID_FILE; break; /* Was it a help request? */ case 'h': showHelp(); exit(0); /* Specify interface to broadcast on */ case 'i': confreadStringCopy(interface, optarg, WS_SIZE -1); xPL_setBroadcastInterface(interface); configOverride |= CO_INTERFACE; break; case 'u': /* Override debug path*/ confreadStringCopy(debugFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New debug path is: %s", debugFile); configOverride |= CO_DEBUG_FILE; break; /* Was it a no-backgrounding request? */ case 'n': /* Mark that we shouldn't background. */ noBackground = TRUE; break; case 'p': /* Override com port*/ confreadStringCopy(comPort, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New com port is: %s", comPort); configOverride |= CO_COM_PORT; break; /* Was it an instance ID ? */ case 's': confreadStringCopy(instanceID, optarg, WS_SIZE); debug(DEBUG_ACTION,"New instance ID is: %s", instanceID); configOverride |= CO_INSTANCE_ID; break; /* Was it a version request? */ case 'v': printf("Version: %s\n", VERSION); exit(0); /* It was something weird.. */ default: fatal("Unhandled getopt return value %d", optchar); } } /* If there were any extra arguments, we should complain. */ if(optind < argc) { fatal("Extra argument on commandline, '%s'", argv[optind]); } /* Load the config file */ if(!(configEntry =confreadScan(configFile, NULL))) exit(1); /* Parse the general section */ /* Com port */ if(!(configOverride & CO_COM_PORT)){ if((p = confreadValueBySectKey(configEntry, "general", "com-port"))){ confreadStringCopy(comPort, p, WS_SIZE); } } /* Debug file */ if(!(configOverride & CO_DEBUG_FILE)){ if((p = confreadValueBySectKey(configEntry, "general", "debug-file"))){ confreadStringCopy(debugFile, p, WS_SIZE); } } /* PID file */ if(!(configOverride & CO_PID_FILE)){ if((p = confreadValueBySectKey(configEntry, "general", "pid-file"))){ confreadStringCopy(pidFile, p, WS_SIZE); } } /* Instance ID */ if(!(configOverride & CO_INSTANCE_ID)){ if((p = confreadValueBySectKey(configEntry, "general", "instance-id"))){ confreadStringCopy(instanceID, p, WS_SIZE); } } /* Interface */ if(!(configOverride & CO_INTERFACE)){ if((p = confreadValueBySectKey(configEntry, "general", "interface"))){ confreadStringCopy(interface, p, WS_SIZE); } } /* Build Zone Map */ if(!(e = confreadGetFirstKeyBySection(configEntry, "zone-map"))) fatal("A valid zone-map section and at least one entry must be defined in the config file"); for(; e; e = confreadGetNextKey(e)){ String plist[3]; const String key = confreadGetKey(e); const String value = confreadGetValue(e); /* Allocate a zone struct */ if(!(zm = mallocz(sizeof(zoneMap_t)))) MALLOC_ERROR; /* Get the zone number */ if(!str2uns(key, &zm->zone_num, 1, 99)) syntax_error(e, configFile,"invalid zone number"); /* Get the parameters */ if(3 != splitString(value, plist, ',', 3)) syntax_error(e, configFile, "3 parameters required"); if(!(zm->zone_name = strdup(plist[0]))) MALLOC_ERROR; if(!(zm->zone_type = strdup(plist[1]))) MALLOC_ERROR; if(!(zm->alarm_type = strdup(plist[2]))) MALLOC_ERROR; /* Hash the zone name */ zm->zone_name_hash = confreadHash(zm->zone_name); /* Free the split string */ free(plist[0]); /* Insert the entry into the zone list */ if(!zoneMapHead) zoneMapHead = zoneMapTail = zm; else{ zm->prev = zoneMapTail; zoneMapTail->next = zm; zoneMapTail = zm; } zoneCount++; } /* EXP zone mapping */ for(e = confreadGetFirstKeyBySection(configEntry, "exp-map"); e; e = confreadGetNextKey(e)){ expMapPtr_t emp; const String keyString = confreadGetKey(e); const String zone = confreadGetValue(e); String plist[3]; unsigned expaddr, expchannel; /* Check the key and zone strings */ if(!(keyString) || (!zone)) syntax_error(e, configFile, "key or zone missing"); /* Split the address and channel */ plist[0] = NULL; if(2 != splitString(keyString, plist, ',', 2)) syntax_error(e, configFile, "left hand side needs 2 numbers separated by a comma"); /* Convert and check address */ if(!str2uns(plist[0], &expaddr, 1, 99)) syntax_error(e, configFile,"address is limited from 1 - 99"); /* Convert and check channel */ if(!str2uns(plist[1], &expchannel, 1, 99)) syntax_error(e, configFile,"channel is limited from 1 - 99"); /* debug(DEBUG_ACTION, "Address: %u, channel: %u, zone: %s", expaddr, expchannel, zone); */ /* Look up zone to ensure it is defined */ if(!(zm = zoneLookup(zone))) syntax_error(e, configFile, "Zone must be defined in zone-map section"); /* Get memory for entry */ if(!(emp = mallocz(sizeof(expMap_t)))) MALLOC_ERROR; /* Initialize entry */ emp->zone_entry = zm; emp->addr = expaddr; emp->channel = expchannel; if(!(emp->zone = strdup(zone))) MALLOC_ERROR; /* Insert into list */ if(!expMapHead){ expMapHead = expMapTail = emp; } else{ expMapTail->next = emp; emp->prev = expMapTail; expMapTail = emp; } /* Free parameter string */ if(plist[0]) free(plist[0]); } /* Turn on library debugging for level 5 */ if(debugLvl >= 5) xPL_setDebugging(TRUE); /* Make sure we are not already running (.pid file check). */ if(pid_read(pidFile) != -1) { fatal("%s is already running", progName); } /* Check to see the serial device exists before we fork */ if(!serio_check_node(comPort)) fatal("Serial device %s does not exist or its permissions are not allowing it to be used.", comPort); /* Fork into the background. */ if(!noBackground) { int retval; debug(DEBUG_STATUS, "Forking into background"); /* * If debugging is enabled, and we are daemonized, redirect the debug output to a log file if * the path to the logfile is defined */ if((debugLvl) && (debugFile[0])) notify_logpath(debugFile); /* Fork and exit the parent */ if((retval = fork())){ if(retval > 0) exit(0); /* Exit parent */ else fatal_with_reason(errno, "parent fork"); } /* * The child creates a new session leader * This divorces us from the controlling TTY */ if(setsid() == -1) fatal_with_reason(errno, "creating session leader with setsid"); /* * Fork and exit the session leader, this prohibits * reattachment of a controlling TTY. */ if((retval = fork())){ if(retval > 0) exit(0); /* exit session leader */ else fatal_with_reason(errno, "session leader fork"); } /* * Change to the root of all file systems to * prevent mount/unmount problems. */ if(chdir("/")) fatal_with_reason(errno, "chdir to /"); /* set the desired umask bits */ umask(022); /* Close STDIN, STDOUT, and STDERR */ close(0); close(1); close(2); } /* Start xPL up */ if (!xPL_initialize(xPL_getParsedConnectionType())) { fatal("Unable to start xPL lib"); } /* Initialize xplrcs service */ /* Create a service and set our application version */ xplService = xPL_createService("hwstar", "xplademco", instanceID); xPL_setServiceVersion(xplService, VERSION); /* * Create a status message object */ xplStatusMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_STATUS); /* * Create trigger message objects */ /* security.gateway */ if(!(xplEventTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER))) fatal("Could not initialize security.gateway trigger"); xPL_setSchema(xplEventTriggerMessage, "security", "gateway"); /* security.zone */ if(!(xplZoneTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER))) fatal("Could not initialize security.zone trigger"); xPL_setSchema(xplZoneTriggerMessage, "security", "zone"); /* Install signal traps for proper shutdown */ signal(SIGTERM, shutdownHandler); signal(SIGINT, shutdownHandler); /* Initialize the COM port */ if(!(serioStuff = serio_open(comPort, COM_BAUD_RATE))) fatal("Could not open com port: %s", comPort); /* Flush any partial commands */ serio_printf(serioStuff, "\r"); usleep(100000); serio_flush_input(serioStuff); /* Ask xPL to monitor our serial device */ if(xPL_addIODevice(serioHandler, 1234, serio_fd(serioStuff), TRUE, FALSE, FALSE) == FALSE) fatal("Could not register serial I/O fd with xPL"); /* Add 1 second tick service */ xPL_addTimeoutHandler(tickHandler, 1, NULL); /* And a listener for all xPL messages */ xPL_addMessageListener(xPLListener, NULL); /* Enable the service */ xPL_setServiceEnabled(xplService, TRUE); /* Update pid file */ if(pid_write(pidFile, getpid()) != 0) { debug(DEBUG_UNEXPECTED, "Could not write pid file '%s'.", pidFile); } /** Main Loop **/ for (;;) { /* Let XPL run forever */ xPL_processMessages(-1); } exit(1); }
int main(int argc, char **argv) { int force = 0, lsock, csock, one = 0, jeden = 1, local_port; int detach = 1, sa_len, conn_limit = 0, optc; char *username = NULL, *bind_host = NULL; struct sockaddr *sa; struct sockaddr_in laddr, caddr; struct sockaddr_in6 laddr6; unsigned int caddrlen = sizeof(caddr); struct passwd *pw = NULL; while ((optc = getopt(argc, argv, "1dv46fHs:l:I:i:hu:m:L:A:p:")) != -1) { switch (optc) { case '1': one = 1; break; case 'd': detach = 0; break; case 'v': verbose = 1; break; case '4': break; case '6': remote_hint = AF_INET; local_hint = AF_INET6; break; case 's': source_host = xstrdup(optarg); break; case 'l': bind_host = xstrdup(optarg); break; case 'r': force = 1; break; case 'i': ircpass = xstrdup(optarg); clear_argv(argv[optind - 1]); break; case 'I': ircsendpass = xstrdup(optarg); clear_argv(argv[optind - 1]); break; case 'h': hexdump = 1; break; case 'u': username = xstrdup(optarg); break; case 'm': map_file = xstrdup(optarg); break; case 'L': conn_limit = atoi(optarg); break; case 'p': pid_file = xstrdup(optarg); break; case 'H': hint_optional = 1; break; default: return 1; } } if (hexdump) verbose = 1; if (verbose) detach = 0; if (detach) verbose = 0; if (argc - optind < 2) { usage(argv[0]); exit(1); } if (username && !(pw = getpwnam(username))) { fprintf(stderr, "%s: unknown user %s\n", argv[0], username); exit(1); } if (map_file) map_read(); local_port = atoi(argv[optind++]); remote_host = argv[optind++]; remote_port = (argc == optind) ? local_port : atoi(argv[optind]); debug("resolving %s\n", remote_host); if (!(sa = resolve_host(remote_host, remote_hint)) && !force) { fprintf(stderr, "%s: unable to resolve host %s\n", argv[0], remote_host); exit(1); } free(sa); sa = NULL; if (bind_host) { debug("resolving %s\n", bind_host); if (!(sa = resolve_host(bind_host, local_hint))) { fprintf(stderr, "%s: unable to resolve host %s\n", argv[0], remote_host); exit(1); } } debug("local: %s,%d; ", (bind_host) ? bind_host : "default", local_port); debug("remote: %s,%d; ", remote_host, remote_port); if (map_file) debug("source: mapped\n"); else debug("source: %s\n", (source_host) ? source_host : "default"); if (local_hint == AF_INET) { lsock = socket(PF_INET, SOCK_STREAM, 0); memset(&laddr, 0, (sa_len = sizeof(laddr))); laddr.sin_family = AF_INET; laddr.sin_port = htons(local_port); if (sa) { memcpy(&laddr.sin_addr, &((struct sockaddr_in*) sa)->sin_addr, sizeof(struct in_addr)); free(sa); } sa = (struct sockaddr*) &laddr; } else { lsock = socket(PF_INET6, SOCK_STREAM, 0); memset(&laddr6, 0, (sa_len = sizeof(laddr6))); laddr6.sin6_family = AF_INET6; laddr6.sin6_port = htons(local_port); if (sa) { memcpy(&laddr6.sin6_addr, &((struct sockaddr_in6*) sa)->sin6_addr, sizeof(struct in6_addr)); free(sa); } sa = (struct sockaddr*) &laddr6; } if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &jeden, sizeof(jeden)) == -1) { perror("setsockopt"); exit(1); } if (bind(lsock, sa, sa_len)) { perror("bind"); exit(1); } if (listen(lsock, 100)) { perror("listen"); exit(1); } if (detach) { int i, ret; signal(SIGHUP, sighup); for (i = 0; i < 3; i++) close(i); ret = fork(); if (ret == -1) { perror("fork"); exit(1); } if (ret) exit(0); } if (pid_file) { FILE *f = fopen(pid_file, "w"); if (!f) debug("warning: cannot write to pidfile (%s)\n", strerror(errno)); else { fprintf(f, "%d", getpid()); fclose(f); } } if (username && ((setgid(pw->pw_gid) == -1) || (setuid(pw->pw_uid) == -1))) { perror("setuid/setgid"); exit(1); } setsid(); signal(SIGCHLD, sigchld); signal(SIGTERM, sigterm); signal(SIGINT, sigterm); signal(SIGHUP, sighup); for (;;) { int ret; fd_set rds; FD_ZERO(&rds); FD_SET(lsock, &rds); if (select(lsock + 1, &rds, NULL, NULL, NULL) == -1) { if (errno == EINTR) continue; perror("select"); break; } if ((csock = accept(lsock, (struct sockaddr*) &caddr, &caddrlen)) == -1) { perror("accept"); break; } inet_ntop(caddr.sin_family, (caddr.sin_family == AF_INET) ? &caddr.sin_addr : (void*) &(((struct sockaddr_in6*)&caddr)->sin6_addr), remote, sizeof(remote)); debug("<%d> connection from %s,%d", csock, remote, ntohs(caddr.sin_port)); if (conn_limit && (conn_count >= conn_limit)) { debug(" -- rejected due to limit.\n"); shutdown(csock, 2); close(csock); continue; } if (conn_limit) { conn_count++; debug(" (no. %d)", conn_count); } fflush(stdout); if ((ret = fork()) == -1) { debug(" -- fork() failed.\n"); shutdown(csock, 2); close(csock); continue; } if (!ret) { signal(SIGHUP, SIG_IGN); close(lsock); debug("\n"); make_tunnel(csock, remote); debug("<%d> connection closed\n", csock); exit(0); } close(csock); if (one) { shutdown(lsock, 2); close(lsock); exit(0); } } close(lsock); exit(1); }
int main(int argc, char *argv[]) { int arglen, ch, len, readstdin = 0; struct passwd *pw; char *p, *endp; pid_t forkpid; #ifndef DEBUG if (geteuid()) errx(1, "NOT super-user"); #endif while ((ch = getopt(argc, argv, "dfhknpr-")) != -1) switch (ch) { case '-': readstdin = 1; break; case 'd': dodump = 1; break; case 'f': dofast = 1; break; case 'h': dohalt = 1; break; case 'k': killflg = 1; break; case 'n': nosync = 1; break; case 'p': dopower = 1; break; case 'r': doreboot = 1; break; default: usage(); } argc -= optind; argv += optind; if (argc < 1) usage(); if (dofast && nosync) { (void)fprintf(stderr, "shutdown: incompatible switches -f and -n.\n"); usage(); } if (doreboot && dohalt) { (void)fprintf(stderr, "shutdown: incompatible switches -h and -r.\n"); usage(); } if (dopower && !dohalt) { (void)fprintf(stderr, "shutdown: switch -p must be used with -h.\n"); usage(); } getoffset(*argv++); if (*argv) { for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) { arglen = strlen(*argv); if ((len -= arglen) <= 2) break; if (p != mbuf) *p++ = ' '; memcpy(p, *argv, arglen); p += arglen; } *p = '\n'; *++p = '\0'; } if (readstdin) { p = mbuf; endp = mbuf + sizeof(mbuf) - 2; for (;;) { if (!fgets(p, endp - p + 1, stdin)) break; for (; *p && p < endp; ++p) ; if (p == endp) { *p = '\n'; *++p = '\0'; break; } } } mbuflen = strlen(mbuf); if (offset) (void)printf("Shutdown at %.24s.\n", ctime(&shuttime)); else (void)printf("Shutdown NOW!\n"); if (!(whom = getlogin())) whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; #ifdef DEBUG (void)putc('\n', stdout); #else (void)setpriority(PRIO_PROCESS, 0, PRIO_MIN); forkpid = fork(); if (forkpid == -1) err(1, "fork"); if (forkpid) { (void)printf("shutdown: [pid %ld]\n", (long)forkpid); exit(0); } setsid(); #endif openlog("shutdown", LOG_CONS, LOG_AUTH); loop(); /* NOTREACHED */ }
int main(int argc, char **argv) { int pid, ret, p[2]; wdir_fd = open(argv[2], O_DIRECTORY); if (wdir_fd < 0) { perror("Can't open wdir"); return 1; } printf("--- Start loop ---\n"); pipe(p); pid = fork(); if (pid < 0) { perror("Can't"); return -1; } if (!pid) { printf(" `- loop: initializing\n"); if (setsid() < 0) exit(1); if (signal(SIGUSR1, sh) == SIG_ERR) exit(1); close(0); close(1); close(2); close(p[0]); ret = SUCC_ECODE; write(p[1], &ret, sizeof(ret)); close(p[1]); while (!stop) sleep(1); exit(SUCC_ECODE); } close(p[1]); /* Wait for kid to start */ ret = -1; read(p[0], &ret, sizeof(ret)); if (ret != SUCC_ECODE) { printf("Error starting loop\n"); goto err; } /* Wait for pipe to get closed, then dump */ read(p[0], &ret, 1); close(p[0]); printf("--- Dump loop ---\n"); criu_init_opts(); criu_set_service_address(argv[1]); criu_set_pid(pid); criu_set_log_file("dump.log"); criu_set_log_level(4); open_imgdir(); ret = criu_dump_iters(next_iter); if (ret < 0) { what_err_ret_mean(ret); kill(pid, SIGKILL); goto err; } printf(" `- Dump succeeded\n"); waitpid(pid, NULL, 0); printf("--- Restore loop ---\n"); criu_init_opts(); criu_set_log_level(4); criu_set_log_file("restore.log"); criu_set_images_dir_fd(cur_imgdir); pid = criu_restore_child(); if (pid <= 0) { what_err_ret_mean(pid); return -1; } printf(" `- Restore returned pid %d\n", pid); kill(pid, SIGUSR1); err: if (waitpid(pid, &ret, 0) < 0) { perror(" Can't wait kid"); return -1; } return chk_exit(ret, SUCC_ECODE); }
void die_you_gravy_sucking_pig_dog(void) { syslog(LOG_NOTICE, "%s by %s: %s", doreboot ? "reboot" : dohalt ? "halt" : "shutdown", whom, mbuf); (void)sleep(2); (void)printf("\r\nSystem shutdown time has arrived\007\007\r\n"); if (killflg) { (void)printf("\rbut you'll have to do it yourself\r\n"); finish(0); } if (dofast) doitfast(); #ifdef DEBUG if (doreboot) (void)printf("reboot"); else if (dohalt) (void)printf("halt"); if (nosync) (void)printf(" no sync"); if (dofast) (void)printf(" no fsck"); if (dodump) (void)printf(" with dump"); (void)printf("\nkill -HUP 1\n"); #else if (doreboot) { execle(_PATH_REBOOT, "reboot", "-l", (nosync ? "-n" : (dodump ? "-d" : NULL)), (dodump ? "-d" : NULL), (char *)NULL, (char *)NULL); syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_REBOOT); warn(_PATH_REBOOT); } else if (dohalt) { execle(_PATH_HALT, "halt", "-l", (dopower ? "-p" : (nosync ? "-n" : (dodump ? "-d" : NULL))), (nosync ? "-n" : (dodump ? "-d" : NULL)), (dodump ? "-d" : NULL), (char *)NULL, (char *)NULL); syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT); warn(_PATH_HALT); } if (access(_PATH_RC, R_OK) != -1) { pid_t pid; struct termios t; int fd; switch ((pid = fork())) { case -1: break; case 0: if (revoke(_PATH_CONSOLE) == -1) perror("revoke"); if (setsid() == -1) perror("setsid"); fd = open(_PATH_CONSOLE, O_RDWR); if (fd == -1) perror("open"); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (fd > 2) close(fd); /* At a minimum... */ tcgetattr(0, &t); t.c_oflag |= (ONLCR | OPOST); tcsetattr(0, TCSANOW, &t); execl(_PATH_BSHELL, "sh", _PATH_RC, "shutdown", (char *)NULL); _exit(1); default: waitpid(pid, NULL, 0); } } (void)kill(1, SIGTERM); /* to single user */ #endif finish(0); }
/* * Detach the controlling terminal, fork, restore syslog stuff, and create * a new session. */ static void fork_session(struct login_context *cxt) { struct sigaction sa, oldsa_hup, oldsa_term; signal(SIGALRM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTSTP, SIG_IGN); memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, &oldsa_hup); /* ignore when TIOCNOTTY */ /* * Detach the controlling tty. * We don't need the tty in a parent who only waits for a child. * The child calls setsid() that detaches from the tty as well. */ ioctl(0, TIOCNOTTY, NULL); /* * We have to beware of SIGTERM, because leaving a PAM session * without pam_close_session() is a pretty bad thing. */ sa.sa_handler = sig_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, &oldsa_term); closelog(); /* * We must fork before setuid(), because we need to call * pam_close_session() as root. */ child_pid = fork(); if (child_pid < 0) { warn(_("fork failed")); pam_setcred(cxt->pamh, PAM_DELETE_CRED); pam_end(cxt->pamh, pam_close_session(cxt->pamh, 0)); sleepexit(EXIT_FAILURE); } if (child_pid) { /* * parent - wait for child to finish, then clean up session */ close(0); close(1); close(2); sa.sa_handler = SIG_IGN; sigaction(SIGQUIT, &sa, NULL); sigaction(SIGINT, &sa, NULL); /* wait as long as any child is there */ while (wait(NULL) == -1 && errno == EINTR) ; openlog("login", LOG_ODELAY, LOG_AUTHPRIV); pam_setcred(cxt->pamh, PAM_DELETE_CRED); pam_end(cxt->pamh, pam_close_session(cxt->pamh, 0)); exit(EXIT_SUCCESS); } /* * child */ sigaction(SIGHUP, &oldsa_hup, NULL); /* restore old state */ sigaction(SIGTERM, &oldsa_term, NULL); if (got_sig) exit(EXIT_FAILURE); /* * Problem: if the user's shell is a shell like ash that doesn't do * setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every * process in the pgrp, will kill us. */ /* start new session */ setsid(); /* make sure we have a controlling tty */ open_tty(cxt->tty_path); openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */ /* * TIOCSCTTY: steal tty from other process group. */ if (ioctl(0, TIOCSCTTY, 1)) syslog(LOG_ERR, _("TIOCSCTTY failed: %m")); signal(SIGINT, SIG_DFL); }
// code from http://www-theorie.physik.unizh.ch/~dpotter/howto/daemonize void daemon_start() { // already a daemon if(getppid() == 1) return; // Trap signals that we expect to recieve signal(SIGCHLD,child_handler); signal(SIGUSR1,child_handler); signal(SIGALRM,child_handler); // Fork off the parent process pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "unable to fork daemon, code=%d (%s)\n", errno, strerror(errno)); exit(1); } // If we got a good PID, then we can exit the parent process. if (pid > 0) { /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or for two seconds to elapse (SIGALRM). pause() should not return. */ alarm(2); pause(); exit(1); } // Create the pid file as the current user. int h = open(PID_FILE, O_RDWR|O_CREAT, 0640); if(h<0) { fprintf(stderr, "unable to create pid file %s, code=%d (%s)\n", PID_FILE, errno, strerror(errno)); exit(1); } char buf[10]; sprintf(buf, "%d", getpid()); write(h, buf, strlen(buf)); close(h); // At this point we are executing as the child process pid_t parent = getppid(); // Cancel certain signals signal(SIGCHLD,SIG_DFL); /* A child process dies */ signal(SIGTSTP,SIG_IGN); /* Various TTY signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */ signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */ /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ pid_t sid = setsid(); if (sid < 0) { fprintf(stderr, "unable to create a new session, code %d (%s)\n", errno, strerror(errno)); exit(1); } /* Change the current working directory. This prevents the current directory from being locked; hence not being able to remove it. */ if ((chdir("/")) < 0) { fprintf(stderr, "unable to change directory to %s, code %d (%s)\n", "/", errno, strerror(errno)); exit(EXIT_FAILURE); } /* Redirect standard files to /dev/null */ freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr); /* Tell the parent process that we are A-okay */ kill(parent, SIGUSR1); isDaemon = true; }
static void daemonize() { int i, sid; FILE *f; /* check if already a daemon */ if (getppid() == 1) return; i = fork(); if (i < 0) { fprintf(stderr, "Fork error...\n"); exit(EXIT_FAILURE); /* fork error */ } if (i > 0) { //printf("Parent done... pid=%u\n", getpid()); exit(EXIT_SUCCESS); /* parent exits */ } /* new child (daemon) continues here */ Trace::disableStdout(); /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } /* Change the current working directory. This prevents the current directory from being locked; hence not being able to remove it. */ if ((chdir("/")) < 0) { exit(EXIT_FAILURE); } /* Redirect standard files to /dev/null */ f = freopen("/dev/null", "r", stdin); if (!f) { perror("redirect stdin:"); exit(EXIT_FAILURE); } f = freopen("/dev/null", "w", stdout); if (!f) { perror("redirect stdout:"); exit(EXIT_FAILURE); } f = freopen("/dev/null", "w", stderr); if (!f) { perror("redirect stderr:"); exit(EXIT_FAILURE); } }
void daemonize(const char *cmd) { int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; /* * Clear file creation mask. */ umask(0); /* * Get maximum number of file descriptors. */ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { fprintf(stderr, "%s: can’t get file limit\n", cmd); exit(1); } /* * Become a session leader to lose controlling TTY. */ if ((pid = fork()) < 0) { fprintf(stderr, "fork error\n"); exit(1); } else if (pid != 0) { // parent exit(0); } setsid(); /* * Ensure future opens won’t allocate controlling TTYs. */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) { fprintf(stderr, "can't ignore SIGHUP\n"); exit(0); } if ((pid = fork()) < 0) { fprintf(stderr, "fork error\n"); exit(1); } else if (pid != 0) { // parent exit(0); } /* * Change the current working directory to the root so * we won’t prevent file systems from being unmounted. */ if (chdir("/") < 0) { fprintf(stderr, "%s: can’t change directory to /\n", cmd); exit(0); } /* * Close all open file descriptors. */ if (rl.rlim_max == RLIM_INFINITY) { rl.rlim_max = 1024; } for (i = 0; i < rl.rlim_max; i++) { close(i); } /* * Attach file descriptors 0, 1, and 2 to /dev/null. */ fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); /* * Initialize the log file. */ openlog(cmd, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } }
int main(int argc, char *argv[]) { int p; int pid; int do_fork = 0; int ttyfd, appfd; pthread_t id; argv++; if (!*argv || !strcmp(*argv, "--help") || !strcmp(*argv, "-h")) { printf("usage: netserve [-d] <port> <program> [args]\n"); exit(0); } if (!strcmp(*argv, "-d")) { do_fork = 1; argv++; } if ((p = atoi(*argv++)) == 0) { fprintf(stderr, "bad port number\n"); exit(0); } if (do_fork) { /* Daemonize */ pid = fork(); if (pid < 0) { perror("fork()"); exit(0); } if (pid > 0) { exit(0); } setsid(); } /* Broken pipes are not a problem */ signal(SIGPIPE, SIG_IGN); /* Get a pseudo tty */ if (openpty(&ttyfd, &appfd, NULL, NULL, NULL) < 0) { perror("open pty"); exit(0); } /* Start the application up with sv[1] as its stdio */ pid = _start_app(argv, appfd); /* Start proxy for input */ if (pthread_create(&id, NULL, _net2tty, (void *)&ttyfd) < 0) { perror("pthread_create"); exit(0); } /* Start proxy for output */ if (pthread_create(&id, NULL, _tty2net, (void *)&ttyfd) < 0) { perror("pthread_create"); exit(0); } /* Setup server */ _server_socket = _setup_socket(p); /* SIGUSR2 restarts the server when the client connection closes */ signal(SIGUSR2, _sig); /* Start the first server */ raise(SIGUSR2); /* Wait for our child to exit */ waitpid(pid, &p, 0); return 0; }
static int miscd_dodaemon(char *argv1, char *daemon) { struct sigaction act; char *commandline; char commbuf[10]; char ch; if (!check_file_writable(PASSFILE)) { fprintf(stderr, "Error! File %s is not writable.\n", PASSFILE); exit(-1); } if (!check_file_writable(BOARDS)) { fprintf(stderr, "Error! File %s is not writable.\n", BOARDS); exit(-1); } truncate(BOARDS, MAXBOARD * sizeof(struct boardheader)); if (load_ucache() != 0) { printf("ft,load ucache error!"); exit(-1); } /* init tmpfs */ sprintf(genbuf1,"%s/home",TMPFSROOT); mkdir(genbuf1,0700); sprintf(genbuf1,"%s/boards",TMPFSROOT); mkdir(genbuf1,0700); for (ch='A';ch<='Z';ch++) { sprintf(genbuf1,"%s/home/%c",TMPFSROOT,ch); mkdir(genbuf1,0700); } resolve_boards(); resolve_utmp(); resolve_guest_table(); if (argv1 != NULL) { switch (fork()) { case -1: printf("faint, i can't fork.\n"); exit(0); break; case 0: break; default: exit(0); break; } commandline = argv1; } else { commandline = commbuf; } setsid(); #ifdef AIX setpgrp(); #elif defined FREEBSD setpgid(0, 0); #else // by zixia setpgrp(0, 0); setpgrp(); #endif #ifdef AIX act.sa_handler = NULL; act.sa_flags = SA_RESTART | SA_NOCLDWAIT; sigaction(SIGCHLD, &act, NULL); #else act.sa_handler = reaper; act.sa_flags = SA_RESTART; sigaction(SIGCHLD, &act, NULL); #endif if (((daemon == NULL) || (!strcmp(daemon, "timed"))) && ((argv1 == NULL) || fork())) { strcpy(commandline, "timed"); timed(); exit(0); } if (((daemon == NULL) || (!strcmp(daemon, "killd"))) && ((argv1 == NULL) || fork())) { strcpy(commandline, "killd"); while (1) { time_t ft; ft = getnextday4am(); do { sleep(ft - time(0)); } while (ft > time(0)); if (argv1 == NULL) { dokilluser(); //doupdategiveupuser(); } else { switch (fork()) { case -1: bbslog("3error", "fork failed\n"); break; case 0: dokilluser(); //doupdategiveupuser(); exit(0); break; default: break; } } switch (fork()) { case -1: bbslog("3error", "fork failed\n"); break; case 0: dokillalldir(); exit(0); break; default: break; } }; exit(0); } if (((daemon == NULL) || (!strcmp(daemon, "userd"))) && ((argv1 == NULL) || fork())) { strcpy(commandline, "userd"); userd(); exit(0); } if ((daemon == NULL) || (!strcmp(daemon, "flushd"))) { strcpy(commandline, "flushd"); flushd(); exit(0); } return 0; }