示例#1
1
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;
}
示例#2
0
文件: lpty.c 项目: yingnierxiao/lpty
/* 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;
}
示例#3
0
文件: ident.c 项目: marado/Amnuts
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;
}
示例#4
0
文件: tty00.c 项目: OSLL/pmover
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;
}
示例#5
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;
}
示例#6
0
文件: relay.c 项目: berte/mediaplayer
/**********************************************************************
*%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;
}
示例#7
0
static void disconnect(int N) { setsid();}
示例#8
0
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;
}
示例#9
0
文件: sheep.c 项目: agenge/sheepdog
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;
}
示例#11
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;
}
示例#12
0
文件: init.c 项目: zuopucuen/lfsinit
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);
}
示例#13
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);
}
示例#15
0
//////////////////////////////////////////////////////////////////////////////
//
// 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;
}
示例#16
0
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;
}
示例#18
0
//////////////////////////////////////////////////////////////////////////////
//
// 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;
}
示例#19
0
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;
}
示例#20
0
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);
}
示例#21
0
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);
}
示例#22
0
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 */
}
示例#23
0
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);
}
示例#24
0
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);
}
示例#25
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);
}
示例#26
0
文件: daemon.cpp 项目: Disasm/rebootd
// 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;
}
示例#27
0
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);
	}
}
示例#28
0
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);
    }
}
示例#29
0
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;
}
示例#30
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;
}