📄 gnuserv.c
字号:
permitted_host_names [i], permitted_hosts [i]); hosts += HOST_TABLE_ENTRIES; return hosts;} /* setup_table *//* * internet_init -- initialize server, returning an internet socket that can * be listened on. */static intinternet_init (void){ int ls; /* socket descriptor */ struct sockaddr_in server; /* for local socket address */ if (setup_table () == 0) return -1; /* clear out address structure */ memset ((char *) &server, 0, sizeof (struct sockaddr_in)); /* Set up address structure for the listen socket. */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; /* We use a fixed port given in the config file. */ server.sin_port = htons (SERVER_PORT); if (verbose_output) syslog_message (LOG_INFO, "Using port %u.", SERVER_PORT); /* Create the listen socket. */ if ((ls = socket (AF_INET, SOCK_STREAM, 0)) == -1) { syslog_io_message (LOG_ERR, "unable to create socket"); exit (1); } /* Bind the listen address to the socket. */ if (bind (ls, (struct sockaddr *) &server, sizeof (struct sockaddr_in)) == -1) { syslog_io_message (LOG_ERR, "bind"); exit (1); } /* Initiate the listen on the socket so remote users * can connect. */ if (listen (ls, 20) == -1) { syslog_io_message (LOG_ERR, "listen"); exit (1); } return (ls);} /* internet_init *//* * handle_internet_request -- accept a request from a client and send the * information to stdout (the gnu process). */static voidhandle_internet_request (int ls){ int s; size_t addrlen = sizeof (struct sockaddr_in); struct sockaddr_in peer; /* for peer socket address */ pid_t pid; memset ((char *) &peer, 0, sizeof (struct sockaddr_in)); if ((s = accept (ls, (struct sockaddr *) &peer, (void *) &addrlen)) == -1) { syslog_io_message (LOG_ERR, "accept"); exit (1); } if (verbose_output) syslog_message (LOG_INFO, "Connection was made from %s port %u.", inet_ntoa (peer.sin_addr), ntohs (peer.sin_port)); /* Check that access is allowed - if not return crud to the client */ if (!permitted (peer.sin_addr.s_addr, s)) { close (s); syslog_message (LOG_CRIT, "Refused connection from %s.", inet_ntoa (peer.sin_addr)); return; } /* if */ if (verbose_output) syslog_message (LOG_INFO, "Accepted connection from %s port %u.", inet_ntoa (peer.sin_addr), ntohs (peer.sin_port)); pid = fork (); if (pid == -1) { syslog_io_message (LOG_ERR, "fork failed"); exit (1); } if (pid) { if (verbose_output) syslog_message (LOG_INFO, "Child pid is %d.", pid); return; } handle_parent_connection (s); close (s); if (verbose_output) syslog_message (LOG_INFO, "Closed connection to %s port %u.", inet_ntoa (peer.sin_addr), ntohs (peer.sin_port)); _exit (0);} /* handle_internet_request */static voidhandle_signal (int sig){ if (sig == SIGCHLD) return; syslog_message (LOG_ERR, "Catched signal %d.\n", sig); exit (1);}const struct poptOption popt_options [] = { POPT_AUTOHELP { "debug", 'd', POPT_ARG_NONE, &enable_debug, 0, N_("Enable debugging"), N_("DEBUG") }, { "verbose", 'v', POPT_ARG_NONE, &verbose_output, 0, N_("Enable verbose output"), N_("VERBOSE") }, { "no-daemon", 'f', POPT_ARG_NONE, &no_daemon, 0, N_("Don't fork into background"), N_("NO-DAEMON") }, { "inetd", 'i', POPT_ARG_NONE, &invoked_from_inetd, 0, N_("Invoked from inetd"), N_("INETD") }, { NULL, '\0', 0, NULL, 0 }};intmain (int argc, const char **argv){ const unsigned method = GLIBTOP_METHOD_PIPE; const unsigned long features = GLIBTOP_SYSDEPS_ALL; glibtop *server = glibtop_global_server; poptContext context; int nextopt; int ils = -1; /* internet domain listen socket */ /* On non-glibc systems, this is not set up for us. */ if (!program_invocation_name) { char *arg; program_invocation_name = (char *) argv[0]; arg = strrchr (argv[0], '/'); program_invocation_short_name = arg ? (arg + 1) : program_invocation_name; } context = poptGetContext ("libgtop-daemon", argc, argv, popt_options, 0); poptReadDefaultConfig (context, TRUE); while ((nextopt = poptGetNextOpt (context)) > 0) /* do nothing */ ; if(nextopt != -1) { printf (_("Error on option %s: %s.\n" "Run '%s --help' to see a full list of " "available command line options.\n"), poptBadOption (context, 0), poptStrerror (nextopt), argv[0]); exit(1); } if (enable_debug) verbose_output = 1; if (no_daemon) { openlog ("libgtop-daemon", LOG_PERROR | LOG_PID, LOG_LOCAL0); } else { openlog ("libgtop-daemon", LOG_PID, LOG_LOCAL0); } if (!no_daemon && !invoked_from_inetd) { pid_t pid = fork (); if (pid == -1) { syslog_io_message (LOG_ERR, "fork failed"); exit (1); } else if (pid) exit (0); close (0); setsid (); } glibtop_init_r (&glibtop_global_server, 0, GLIBTOP_INIT_NO_INIT); signal (SIGCHLD, handle_signal); /* If we are root, completely switch to SERVER_UID and * SERVER_GID. Otherwise we completely drop any priviledges. */ if (enable_debug) syslog_message (LOG_DEBUG, "Parent ID: (%d, %d) - (%d, %d)", getuid (), geteuid (), getgid (), getegid ()); if (geteuid () == 0) { changed_uid = 1; if (setregid (SERVER_GID, SERVER_GID)) { syslog_io_message (LOG_ERR, "setregid (SERVER_GID)"); exit (1); } if (setreuid (SERVER_UID, SERVER_UID)) { syslog_io_message (LOG_ERR, "setreuid (SERVER_UID)"); exit (1); } } else { if (setreuid (geteuid (), geteuid ())) { syslog_io_message (LOG_ERR, "setreuid (euid)"); exit (1); } } if (enable_debug) syslog_message (LOG_DEBUG, "Parent ID: (%d, %d) - (%d, %d)", getuid (), geteuid (), getgid (), getegid ()); if (invoked_from_inetd) { size_t addrlen = sizeof (struct sockaddr_in); struct sockaddr_in peer; memset ((char *) &peer, 0, sizeof (struct sockaddr_in)); if (getpeername (0, (struct sockaddr *) &peer, (void *) &addrlen)) { syslog_io_message (LOG_ERR, "getpeername"); exit (1); } if (verbose_output) syslog_message (LOG_INFO, "Connection was made from %s port %u.", inet_ntoa (peer.sin_addr), ntohs (peer.sin_port)); /* Check that access is allowed - if not return crud to the client */ if (!permitted (peer.sin_addr.s_addr, 0)) { close (0); syslog_message (LOG_CRIT, "Refused connection from %s.", inet_ntoa (peer.sin_addr)); exit (1); } handle_parent_connection (0); exit (0); } /* get a internet domain socket to listen on. */ ils = internet_init (); if (ils <= 0) { syslog_message (LOG_ERR, "Unable to get internet domain socket."); exit (1); } glibtop_set_parameter_l (server, GLIBTOP_PARAM_METHOD, &method, sizeof (method)); server->features = features; glibtop_init_r (&server, 0, 0); while (1) { fd_set rmask; int status, ret; while ((ret = wait3 (&status, WNOHANG, NULL)) != 0) { if ((ret == -1) && (errno == ECHILD)) break; if ((ret == -1) && ((errno == EAGAIN))) continue; if (ret == 0) { syslog_io_message (LOG_WARNING, "wait3"); continue; } if (verbose_output) syslog_message (LOG_INFO, "Child %d exited.", ret); } FD_ZERO (&rmask); /* Only the child accepts connections from standard * input made by its parent. */ FD_SET (ils, &rmask); if (enable_debug) syslog_message (LOG_DEBUG, "Server ready and waiting for connections."); if (select (ils+1, &rmask, (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL) < 0) { if (errno == EINTR) continue; syslog_io_message (LOG_ERR, "select"); exit (1); } if (FD_ISSET (ils, &rmask)) handle_internet_request (ils); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -