📄 gatherd.c
字号:
} if (access(cffile, R_OK)) { Log("WARNING: Configuration file not readable: %s\n", cffile); cffile = NULL; } /* check to see if allzipped is up-to-date */ if (indexfile && allzipped) { struct stat sba, sbi; stat(allzipped, &sba); stat(indexfile, &sbi); if (sba.st_mtime < sbi.st_mtime) { Log("WARNING: Cache file out-of-date: %s\n", allzipped); allzipped = NULL; } } if (cffile) { load_configuration(cffile); } else { allow_all = 1; allow_hosts[0] = deny_hosts[0] = NULL; } /* Check to see if the program is being run via inetd */ if (strstr(pgm, "in.gatherd") != NULL) { write_pid(); exit(serve_client(0)); } /* Stand-alone daemon needs a port number */ if (argc == 0) { (void) unlink(pidfile); usage(); } master_slave_mode(atoi(*argv)); exit(0);}/* * master_slave_mode() - Enters a Master-Slave mode to process client * request. For each client connection, it spawns a process to * handle the request. */static void master_slave_mode(portnumber) int portnumber;{ struct sockaddr_in sin, cin; int s, cs, clen, pid, on = 1, i; FILE *logfp;#ifdef USE_TIMEOUT fd_set R; struct timeval to; int x; struct stat sb;#endif if (portnumber < 1) { fatal("Illegal port number: %d\n", portnumber); } disconnect(); /* be a friendly daemon */ logfp = fopen(logfile, "a+"); if (logfp != NULL) { setbuf(logfp, NULL); init_log(logfp, logfp); } else { init_log(NULL, NULL); /* we have no choice */ } memset(&sin, '\0', sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(portnumber); if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { log_errno("socket"); exit(1); } if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on))) < 0) { log_errno("setsockopt (SO_REUSEADDR = on)"); exit(1); } if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { log_errno("bind"); (void) close(s); exit(1); } if (listen(s, 5) < 0) { log_errno("listen"); exit(1); } clen = sizeof(cin); write_pid();#ifdef NSIG for (i = 1; i < NSIG; i++) {#else for (i = 1; i < _sys_nsig; i++) {#endif if (i == SIGCHLD || i == SIGWINCH || i == SIGSEGV) continue; signal(i, sigcleanup); } Log("Ready to serve information...\n"); while (1) {#ifdef USE_TIMEOUT to.tv_sec = 10; /* Lunix modifies 'to' on return */ to.tv_usec = 0; FD_ZERO(&R); FD_SET(s, &R); x = select(s + 1, &R, 0, 0, &to); if (x < 0) { if (errno == EINTR) continue; log_errno("select"); unlink(pidfile); exit(1); } else /* If select times out, check for the existance of the */ /* pidfile. If gone, somebody wants us dead, so die. */ if (x == 0) { if (stat(pidfile, &sb) < 0) exit(1); continue; }#endif if ((cs = accept(s, (struct sockaddr *) &cin, &clen)) < 0) { if (errno == EINTR) continue; log_errno("accept"); unlink(pidfile); exit(1); } setsocket_linger(cs, 30); /* 30 sec linger time */ if ((pid = fork()) < 0) { log_errno("fork"); unlink(pidfile); exit(1); } if (pid == 0) { /* child */ logfp = fopen(logfile, "a+"); if (logfp != NULL) { setbuf(logfp, NULL); init_log(logfp, logfp); } else { init_log(NULL, NULL); /* we have no choice */ } close(s); exit(serve_client(cs)); } close(cs); /* parent */ while (waitpid(-1, NULL, WNOHANG) > 0); /* catch any zombies */ }}/* * disconnect() - Disconnect the process from the controlling terminal. * Adapted from Harvest's floodd daemon in the replicator. */static void disconnect(){ int pid, fd;#ifdef SIGTTOU signal(SIGTTOU, SIG_IGN);#endif#ifdef SIGTTIN signal(SIGTTIN, SIG_IGN);#endif#ifdef SIGTSTP signal(SIGTSTP, SIG_IGN);#endif if ((pid = fork()) < 0) { log_errno("fork"); return; } if (pid) { /* parent */ exit(0); /* quietly exit to let child do the work */ } (void) setsid(); /* Logging beneath here will not work */ /* Close all file descriptors */ close_all_fds(0); /* Redirect the stdin, stdout, and stderr to /dev/null */ if ((fd = open("/dev/null", O_RDWR)) < 0) { exit(1); } (void) dup2(fd, 0); (void) dup2(fd, 1); (void) dup2(fd, 2);}static void load_configuration(filename) char *filename;{ FILE *fp; char buf[BUFSIZ], *s; int a = 0, d = 0; extern void Tolower(); memset(allow_hosts, '\0', BUFSIZ * sizeof(char *)); memset(deny_hosts, '\0', BUFSIZ * sizeof(char *)); allow_all = deny_all = 0; if ((fp = fopen(filename, "r")) == NULL) { log_errno(filename); return; } while (fgets(buf, BUFSIZ, fp)) { if (buf[0] == '#' || buf[0] == '\n') continue; if (!strncmp(buf, "Allow", 5)) { s = strtok(buf, " \t\n"); while ((s = strtok(NULL, " \t\n")) != NULL) { if (!strcmp(s, "all")) { allow_all = 1;#ifdef DEBUG Log("Allowing access for all hosts\n");#endif break; } allow_hosts[a] = strdup(s); Tolower(allow_hosts[a]);#ifdef DEBUG Log("Allowing access for %s\n", allow_hosts[a]);#endif a++; } } else if (!strncmp(buf, "Deny", 4)) { s = strtok(buf, " \t\n"); while ((s = strtok(NULL, " \t\n")) != NULL) { if (!strcmp(s, "all")) { deny_all = 1;#ifdef DEBUG Log("Denying access for all hosts\n");#endif break; } deny_hosts[d] = strdup(s); Tolower(deny_hosts[d]);#ifdef DEBUG Log("Denying access for %s\n", deny_hosts[d]);#endif d++; } } else if (!strncmp(buf, "Gzip", 4)) { (void) strtok(buf, " \t\n"); if ((s = strtok(NULL, " \t\n")) != NULL) cmd_gzip = xstrdup(s); } } fclose(fp); allow_hosts[a] = NULL; deny_hosts[d] = NULL; if (allow_all && deny_all) { errorlog("Illegal Configuration!\n"); errorlog("Cannot have both \"Allow all\" and \"Deny all\"\n"); exit(1); }}static void write_pid(){ FILE *fp; /* Write the pid to a file */ if ((fp = fopen(pidfile, "w")) != NULL) { fprintf(fp, "%d\n", master_pid = getpid()); fclose(fp); } else { log_errno(pidfile); }}int read_pid(){ FILE *fp; int pid = -1; if ((fp = fopen(pidfile, "r")) != NULL) { fscanf(fp, "%d\n", &pid); fclose(fp); } else { log_errno(pidfile); } return pid;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -