From owner-svn-src-projects@FreeBSD.ORG Sun Aug 22 16:22:46 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 202FB1065866; Sun, 22 Aug 2010 16:22:44 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4613B8FC17; Sun, 22 Aug 2010 16:22:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7MGMiC2008837; Sun, 22 Aug 2010 16:22:44 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7MGMiV7008835; Sun, 22 Aug 2010 16:22:44 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <201008221622.o7MGMiV7008835@svn.freebsd.org> From: Attilio Rao Date: Sun, 22 Aug 2010 16:22:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211631 - projects/sv/usr.sbin/netdumpsrv X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Aug 2010 16:22:46 -0000 Author: attilio Date: Sun Aug 22 16:22:44 2010 New Revision: 211631 URL: http://svn.freebsd.org/changeset/base/211631 Log: - Fix the arguments passing to the process by using the getopt interface - Always close the process via the exit(3) interface - Fix some points where the exit(3) was invoked without a prior cleanup of pidfile - Add a couple of comments explaining how the error handling happpens Modified: projects/sv/usr.sbin/netdumpsrv/netdump_server.c Modified: projects/sv/usr.sbin/netdumpsrv/netdump_server.c ============================================================================== --- projects/sv/usr.sbin/netdumpsrv/netdump_server.c Sun Aug 22 16:13:51 2010 (r211630) +++ projects/sv/usr.sbin/netdumpsrv/netdump_server.c Sun Aug 22 16:22:44 2010 (r211631) @@ -55,6 +55,10 @@ /* Host name length (keep at least as big as INET_ADDRSTRLEN) */ #define MAXHOSTNAMELEN 256 +#define PFLAGS_ABIND 0x01 +#define PFLAGS_DDIR 0x02 +#define PFLAGS_SCRIPT 0x04 + #define LOGERR(m, ...) \ syslog(LOG_ERR | LOG_DAEMON, (m), ## __VA_ARGS__) #define LOGERR_PERROR(m) \ @@ -86,6 +90,7 @@ struct netdump_client SLIST_HEAD(, netdump_client) clients = SLIST_HEAD_INITIALIZER(clients); char dumpdir[MAXPATHLEN]; +uint32_t pflags = 0; char *handler_script=NULL; time_t now; int do_shutdown; @@ -118,6 +123,15 @@ static void send_ack(struct netdump_cl struct netdump_msg *msg); static void signal_shutdown(int sig); static void timeout_clients(void); +static void usage(const char *cmd); + +static void +usage(const char *cmd) +{ + + fprintf(stderr, "Usage: %s [-a bind_addr] [-d dump_dir] [-i script]\n", + cmd); +} static struct netdump_client *alloc_client(struct sockaddr_in *sip) { @@ -296,6 +310,10 @@ static void exec_handler(struct netdump_ assert(client != NULL); + /* If no script is specified this is a no-op. */ + if ((pflags & PFLAGS_SCRIPT) == 0) + return; + pid=fork(); /* @@ -653,6 +671,7 @@ static void eventloop() LOGERR_PERROR("select()"); /* Errors with select() probably won't go away if we just try to * select() again */ + pidfile_remove(pfh); exit(1); } @@ -672,6 +691,7 @@ static void eventloop() if (errno != EAGAIN) { + pidfile_remove(pfh); LOGERR_PERROR("recvfrom()"); exit(1); } @@ -767,6 +787,7 @@ int main(int argc, char **argv) struct stat statbuf; struct sockaddr_in bindaddr; struct sigaction sa; + int ch; pfh = pidfile_open(NULL, 0600, NULL); if (pfh == NULL) { @@ -777,65 +798,82 @@ int main(int argc, char **argv) exit(1); } - /* Check argc and set the bindaddr and handler_script */ - switch (argc) - { - case 4: - handler_script = strdup(argv[3]); - if (access(handler_script, F_OK|X_OK)) - { - pidfile_remove(pfh); - fputs("Warning: may be unable to execute handler script\n", - stderr); - free(handler_script); - return 1; - } - case 3: - if (!inet_aton(argv[2], &bindip)) - { - pidfile_remove(pfh); - fputs("Invalid bind IP specified\n", stderr); - return 1; - } - printf("Listening on IP %s\n", argv[2]); - break; - case 2: - bindip.s_addr = INADDR_ANY; - puts("Listening on all interfaces"); - break; + while ((ch = getopt(argc, argv, "a:d:i:")) != -1) { + switch (ch) { + case 'a': + pflags |= PFLAGS_ABIND; + if (!inet_aton(optarg, &bindip)) { + pidfile_remove(pfh); + fprintf(stderr, "Invalid bind IP specified\n"); + exit(1); + } + printf("Listening on IP %s\n", optarg); + break; + case 'd': + pflags |= PFLAGS_DDIR; + bzero(dumpdir, sizeof(dumpdir)); + strncpy(dumpdir, optarg, sizeof(dumpdir) - 1); + break; + case 'i': + pflags |= PFLAGS_SCRIPT; + + /* + * When suddently closing the process for an error, + * it is unuseful to take care of handler_script deallocation + * as long as the process will _exit(2) anyway. + */ + handler_script = strdup(optarg); + if (handler_script == NULL) { + pidfile_remove(pfh); + perror("strdup()"); + fprintf(stderr, "Unable to set script file\n"); + exit(1); + } + if (access(handler_script, F_OK|X_OK)) { + pidfile_remove(pfh); + perror("access()"); + fprintf(stderr, "Unable to access script file\n"); + exit(1); + } + break; default: - pidfile_remove(pfh); - fprintf(stderr, "Usage: %s " - "[bind IP [handler script]]\n", argv[0]); - return 1; + pidfile_remove(pfh); + usage(argv[0]); + exit(1); + } + } + if ((pflags & PFLAGS_ABIND) == 0) { + bindip.s_addr = INADDR_ANY; + printf("Default: listening on all interfaces\n"); + } + if ((pflags & PFLAGS_DDIR) == 0) { + strcpy(dumpdir, "/var/crash"); + printf("Default: dumping on /var/crash/\n"); } /* Check dump location for sanity */ - if (stat(argv[1], &statbuf)) - { + if (stat(dumpdir, &statbuf)) { pidfile_remove(pfh); - perror("stat"); - fputs("Invalid dump location specified\n", stderr); - return 1; + perror("stat()"); + fprintf(stderr, "Invalid dump location specified\n"); + exit(1); } - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) - { + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { pidfile_remove(pfh); - fputs("Dump location is not a directory\n", stderr); - return 1; + fprintf(stderr, "Dump location is not a directory\n"); + exit(1); } - if (access(argv[1], F_OK|W_OK)) - { - fprintf(stderr, "Warning: May be unable to write into dump " - "location: %s\n", strerror(errno)); + if (access(dumpdir, F_OK|W_OK)) { + fprintf(stderr, + "Warning: May be unable to write into dump location: %s\n", + strerror(errno)); } - strncpy(dumpdir, argv[1], sizeof(dumpdir)-1); - dumpdir[sizeof(dumpdir)-1]='\0'; if (daemon(0, 0) == -1) { pidfile_remove(pfh); perror("daemon()"); - return 1; + fprintf(stderr, "Impossible to demonize the process\n"); + exit(1); } pidfile_write(pfh); @@ -844,7 +882,7 @@ int main(int argc, char **argv) { pidfile_remove(pfh); LOGERR_PERROR("socket()"); - return 1; + exit(1); } bzero(&bindaddr, sizeof(bindaddr)); bindaddr.sin_len = sizeof(bindaddr); @@ -854,15 +892,15 @@ int main(int argc, char **argv) if (bind(sock, (struct sockaddr *)&bindaddr, sizeof(bindaddr))) { pidfile_remove(pfh); - LOGERR_PERROR("bind()"); close(sock); - return 1; + LOGERR_PERROR("bind()"); + exit(1); } if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { pidfile_remove(pfh); - LOGERR_PERROR("fcntl()"); close(sock); - return 1; + LOGERR_PERROR("fcntl()"); + exit(1); } /* Signal handlers */ @@ -871,9 +909,9 @@ int main(int argc, char **argv) if (sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL)) { pidfile_remove(pfh); - LOGERR_PERROR("sigaction(SIGINT | SIGTERM)"); close(sock); - return 1; + LOGERR_PERROR("sigaction(SIGINT | SIGTERM)"); + exit(1); } bzero(&sa, sizeof(sa)); sa.sa_handler = SIG_IGN; @@ -883,7 +921,7 @@ int main(int argc, char **argv) pidfile_remove(pfh); LOGERR_PERROR("sigaction(SIGCHLD)"); close(sock); - return 1; + exit(1); } LOGINFO("Waiting for clients.\n"); @@ -891,12 +929,7 @@ int main(int argc, char **argv) do_shutdown=0; eventloop(); - if (handler_script) - { - free(handler_script); - } pidfile_remove(pfh); - return 0; }