int main (int argc, char **argv) { register int s; struct servent *sp; void dologout (void); set_program_name (argv[0]); iu_argp_init ("uucpd", default_program_authors); argp_parse (&argp, argc, argv, 0, NULL, NULL); environ = nenv; sp = getservbyname ("uucp", "tcp"); if (sp == NULL) { perror ("uucpd: getservbyname"); exit (EXIT_FAILURE); } if (fork ()) exit (EXIT_SUCCESS); if ((s = open (PATH_TTY, O_RDWR)) >= 0) { ioctl (s, TIOCNOTTY, (char *) 0); close (s); } memset (&myctladdr, 0, sizeof (myctladdr)); myctladdr.sin_family = AF_INET; myctladdr.sin_port = sp->s_port; }
int main (int argc, char *argv[]) { int index; set_program_name (argv[0]); iu_argp_init ("talk", program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); argc -= index; argv += index; if (argc == 0) { printf ("Usage: talk user [ttyname]\n"); exit (-1); } if (!isatty (0)) { printf ("Standard input must be a tty, not a pipe or a file\n"); exit (-1); } get_names (argc, argv); init_display (); open_ctl (); open_sockt (); start_msgs (); if (!check_local ()) invite_remote (); end_msgs (); set_edit_chars (); talk (); }
int main (int argc, char *argv[]) { /* Parse command line */ iu_argp_init ("talkd", program_authors); argp_parse (&argp, argc, argv, 0, NULL, NULL); read_acl (acl_file); talkd_init (); talkd_run (0); return 0; }
int main (int argc, char *argv[]) { set_program_name (argv[0]); iu_argp_init ("dnsdomainname", program_authors); argp_parse (&argp, argc, argv, 0, NULL, NULL); dnsdomainname (); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int index; set_program_name (argv[0]); /* Parse command line */ iu_argp_init ("rlogind", program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); openlog ("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); argc -= index; if (argc > 0) { syslog (LOG_ERR, "%d extra arguments", argc); exit (1); } signal (SIGHUP, SIG_IGN); if (!local_domain_name) { char *p = localhost (); if (!p) { syslog (LOG_ERR, "can't determine local hostname"); exit (1); } local_dot_count = 2; local_domain_name = topdomain (p, local_dot_count); } else { char *p; local_dot_count = 0; for (p = local_domain_name; *p; p++) if (*p == '.') local_dot_count++; } if (mode == MODE_DAEMON) rlogin_daemon (maxchildren, port); else exit (rlogind_mainloop (fileno (stdin), fileno (stdout))); return 0; }
int main (int argc, char **argv) { int index; int status = 0; set_program_name (argv[0]); if (getuid () == 0) is_root = true; /* Parse command line */ iu_argp_init ("ping6", program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); ping = ping_init (0, getpid ()); if (ping == NULL) /* ping_init() prints our error message. */ exit (1); setsockopt (ping->ping_fd, SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (one)); /* Reset root privileges */ setuid (getuid ()); argc -= index; argv += index; if (count != 0) ping_set_count (ping, count); if (socket_type != 0) ping_set_sockopt (ping, socket_type, &one, sizeof (one)); if (options & OPT_INTERVAL) ping_set_interval (ping, interval); init_data_buffer (patptr, pattern_len); while (argc--) { status |= ping_echo (*argv++); ping_reset (ping); } return status; }
int main (int argc, char **argv) { struct addrinfo hints, *res; trace_t trace; set_program_name (argv[0]); /* Parse command line */ iu_argp_init ("traceroute", program_authors); argp_parse (&argp, argc, argv, 0, NULL, NULL); /* Hostname lookup first for better information */ memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_CANONNAME; if ((hostname == NULL) || (*hostname == '\0') || getaddrinfo (hostname, NULL, &hints, &res)) error (EXIT_FAILURE, 0, "unknown host"); memcpy (&dest, res->ai_addr, res->ai_addrlen); dest.sin_port = htons (opt_port); getnameinfo (res->ai_addr, res->ai_addrlen, addrstr, sizeof (addrstr), NULL, 0, NI_NUMERICHOST); printf ("traceroute to %s (%s), %d hops max\n", res->ai_canonname, addrstr, opt_max_hops); freeaddrinfo (res); trace_init (&trace, dest, opt_type); int hop = 1; while (!stop) { if (hop > opt_max_hops) exit (EXIT_SUCCESS); do_try (&trace, hop, opt_max_hops, opt_max_tries); trace_inc_ttl (&trace); trace_inc_port (&trace); hop++; } exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { struct sockaddr_in sin; set_program_name (argv[0]); iu_argp_init ("tftp", default_program_authors); argp_parse (&argp, argc, argv, 0, NULL, NULL); sp = getservbyname ("tftp", "udp"); if (sp == 0) { fprintf (stderr, "tftp: udp/tftp: unknown service\n"); exit (1); } f = socket (AF_INET, SOCK_DGRAM, 0); if (f < 0) { perror ("tftp: socket"); exit (3); } memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; if (bind (f, (struct sockaddr *) &sin, sizeof (sin)) < 0) { perror ("tftp: bind"); exit (1); } strcpy (mode, "netascii"); signal (SIGINT, intr); if (hostport_argc > 1) { if (setjmp (toplevel) != 0) exit (0); setpeer (hostport_argc, hostport_argv); } if (setjmp (toplevel) != 0) putchar ('\n'); command (); }
int main (int argc, char **argv) { int index; struct passwd *pw; struct servent *sp; sigset_t sigs, osigs; int asrsh, rem; pid_t pid = 0; uid_t uid; char *args, *host; set_program_name (argv[0]); asrsh = 0; host = user = NULL; /* If called as something other than "rsh", use it as the host name */ { char *p = strrchr (argv[0], '/'); if (p) ++p; else p = argv[0]; if (strcmp (p, "rsh")) host = p; else asrsh = 1; } /* Parse command line */ iu_argp_init ("rsh", default_program_authors); argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &index, NULL); if (index < argc) host = argv[index++]; /* To few args. */ if (!host) error (EXIT_FAILURE, 0, "host not specified"); /* If no further arguments, must have been called as rlogin. */ if (!argv[index]) { if (asrsh) *argv = (char *) "rlogin"; seteuid (getuid ()); setuid (getuid ()); execv (PATH_RLOGIN, argv); error (EXIT_FAILURE, errno, "cannot execute %s", PATH_RLOGIN); } argc -= index; argv += index; /* We must be setuid root. */ if (geteuid ()) error (EXIT_FAILURE, 0, "must be setuid root.\n"); if (!(pw = getpwuid (uid = getuid ()))) error (EXIT_FAILURE, 0, "unknown user id"); /* Accept user1@host format, though "-l user2" overrides user1 */ { char *p = strchr (host, '@'); if (p) { *p = '\0'; if (!user && p > host) user = host; host = p + 1; if (*host == '\0') error (EXIT_FAILURE, 0, "empty host name"); } } #if defined KERBEROS || defined SHISHI # ifdef ENCRYPTION /* -x turns off -n */ if (doencrypt) null_input_option = 0; # endif #endif args = copyargs (argv); sp = NULL; #ifdef KERBEROS if (use_kerberos) { sp = getservbyname ((doencrypt ? "ekshell" : "kshell"), "tcp"); if (sp == NULL) { use_kerberos = 0; warning ("can't get entry for %s/tcp service", doencrypt ? "ekshell" : "kshell"); } } #elif defined(SHISHI) if (use_kerberos) { sp = getservbyname ("kshell", "tcp"); if (sp == NULL) { use_kerberos = 0; warning ("can't get entry for %s/tcp service", "kshell"); } } #endif if (sp == NULL) sp = getservbyname ("shell", "tcp"); if (sp == NULL) error (EXIT_FAILURE, 0, "shell/tcp: unknown service"); #if defined KERBEROS || defined SHISHI try_connect: if (use_kerberos) { struct hostent *hp; /* fully qualify hostname (needed for krb_realmofhost) */ hp = gethostbyname (host); if (hp != NULL && !(host = strdup (hp->h_name))) error (EXIT_FAILURE, errno, "strdup"); # if defined KERBEROS rem = KSUCCESS; errno = 0; if (dest_realm == NULL) dest_realm = krb_realmofhost (host); # elif defined (SHISHI) rem = SHISHI_OK; errno = 0; # endif # ifdef ENCRYPTION if (doencrypt) # if defined SHISHI { int i; char *term; term = xmalloc (strlen (args) + 4); strcpy (term, "-x "); strcat (term, args); rem = krcmd_mutual (&h, &host, sp->s_port, &user, term, &rfd2, dest_realm, &enckey); if (rem > 0) { keytype = shishi_key_type (enckey); keylen = shishi_cipher_blocksize (keytype); ivtab[0] = &iv1; ivtab[1] = &iv2; ivtab[2] = &iv3; ivtab[3] = &iv4; for (i = 0; i < 4; i++) { ivtab[i]->ivlen = keylen; switch (keytype) { case SHISHI_DES_CBC_CRC: case SHISHI_DES_CBC_MD4: case SHISHI_DES_CBC_MD5: case SHISHI_DES_CBC_NONE: case SHISHI_DES3_CBC_HMAC_SHA1_KD: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, 2 * i + 1 * (i < 2) - 4 * (i >= 2), ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), ivtab[i]->iv, ivtab[i]->ivlen); break; case SHISHI_ARCFOUR_HMAC: case SHISHI_ARCFOUR_HMAC_EXP: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i; ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), NULL, 0); break; default: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, 0, ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), ivtab[i]->iv, ivtab[i]->ivlen); } } } free (term); } else # else rem = krcmd_mutual (&host, sp->s_port, user, args, &rfd2, dest_realm, &cred, schedule); else # endif # endif rem = krcmd ( # if defined SHISHI &h, &host, sp->s_port, &user, args, &rfd2, dest_realm); # else &host, sp->s_port, user, args, &rfd2, dest_realm); # endif if (rem < 0) { use_kerberos = 0; sp = getservbyname ("shell", "tcp"); if (sp == NULL) error (EXIT_FAILURE, 0, "shell/tcp: unknown service"); if (errno == ECONNREFUSED) warning ("remote host doesn't support Kerberos"); if (errno == ENOENT) warning ("can't provide Kerberos auth data"); goto try_connect; } }
int main (int argc, char *argv[], char *envp[]) { int index; struct servtab *sep; int dofork; pid_t pid; set_program_name (argv[0]); Argv = argv; if (envp == 0 || *envp == 0) envp = argv; while (*envp) envp++; LastArg = envp[-1] + strlen (envp[-1]); /* Parse command line */ iu_argp_init ("inetd", program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); if (resolve_option) env_option = true; if (index < argc) { int i; config_files = calloc (argc - index + 1, sizeof (*config_files)); for (i = 0; index < argc; index++, i++) { config_files[i] = strdup (argv[index]); } } else { config_files = calloc (3, sizeof (*config_files)); config_files[0] = newstr (PATH_INETDCONF); config_files[1] = newstr (PATH_INETDDIR); } if (!debug) { daemon (0, 0); } openlog ("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); { FILE *fp = fopen (PATH_INETDPID, "w"); if (fp != NULL) { fprintf (fp, "%d\n", getpid ()); fclose (fp); } else syslog (LOG_CRIT, "can't open %s: %s\n", PATH_INETDPID, strerror (errno)); } signal_set_handler (SIGALRM, retry); config (0); signal_set_handler (SIGHUP, config); signal_set_handler (SIGCHLD, reapchild); signal_set_handler (SIGPIPE, SIG_IGN); { /* space for daemons to overwrite environment for ps */ #define DUMMYSIZE 100 char dummy[DUMMYSIZE]; memset (dummy, 'x', DUMMYSIZE - 1); dummy[DUMMYSIZE - 1] = '\0'; setenv ("inetd_dummy", dummy, 1); } for (;;) { int n, ctrl; fd_set readable; if (nsock == 0) { SIGSTATUS stat; sigstatus_empty (stat); signal_block (NULL); while (nsock == 0) inetd_pause (stat); signal_unblock (NULL); } readable = allsock; if ((n = select (maxsock + 1, &readable, NULL, NULL, NULL)) <= 0) { if (n < 0 && errno != EINTR) syslog (LOG_WARNING, "select: %m"); sleep (1); continue; } for (sep = servtab; n && sep; sep = sep->se_next) if (sep->se_fd != -1 && FD_ISSET (sep->se_fd, &readable)) { n--; if (debug) fprintf (stderr, "someone wants %s\n", sep->se_service); if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { struct sockaddr_in sa_client; socklen_t len = sizeof (sa_client); ctrl = accept (sep->se_fd, (struct sockaddr *) &sa_client, &len); if (debug) fprintf (stderr, "accept, ctrl %d\n", ctrl); if (ctrl < 0) { if (errno != EINTR) syslog (LOG_WARNING, "accept (for %s): %m", sep->se_service); continue; } if (env_option) prepenv (ctrl, sa_client); } else ctrl = sep->se_fd; signal_block (NULL); pid = 0; dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork); if (dofork) { if (sep->se_count++ == 0) gettimeofday (&sep->se_time, NULL); else if ((sep->se_max && sep->se_count > sep->se_max) || sep->se_count >= toomany) { struct timeval now; gettimeofday (&now, NULL); if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) { sep->se_time = now; sep->se_count = 1; } else { syslog (LOG_ERR, "%s/%s server failing (looping), service terminated", sep->se_service, sep->se_proto); close_sep (sep); if (! sep->se_wait && sep->se_socktype == SOCK_STREAM) close (ctrl); signal_unblock (NULL); if (!timingout) { timingout = 1; alarm (RETRYTIME); } continue; } } pid = fork (); } if (pid < 0) { syslog (LOG_ERR, "fork: %m"); if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) close (ctrl); signal_unblock (NULL); sleep (1); continue; } if (pid && sep->se_wait) { sep->se_wait = pid; if (sep->se_fd >= 0) { FD_CLR (sep->se_fd, &allsock); nsock--; } } signal_unblock (NULL); if (pid == 0) { if (debug && dofork) setsid (); if (dofork) { int sock; if (debug) fprintf (stderr, "+ Closing from %d\n", maxsock); for (sock = maxsock; sock > 2; sock--) if (sock != ctrl) close (sock); } run_service (ctrl, sep); } if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) close (ctrl); } } }
int main (int argc, char *argv[]) { int top; int index; struct passwd *pw = NULL; char *cp; set_program_name (argv[0]); sp = getservbyname ("ftp", "tcp"); if (sp == 0) error (EXIT_FAILURE, 0, "ftp/tcp: unknown service"); doglob = 1; interactive = 1; autologin = 1; /* Parse command line */ iu_argp_init ("ftp", default_program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); argc -= index; argv += index; fromatty = isatty (fileno (stdin)); if (fromatty) { verbose++; if (!prompt) prompt = DEFAULT_PROMPT; } cpend = 0; /* no pending replies */ proxy = 0; /* proxy not active */ passivemode = 0; /* passive mode not active */ crflag = 1; /* strip c.r. on ascii gets */ sendport = -1; /* not using ports */ /* * Set up the home directory in case we're globbing. */ cp = getlogin (); if (cp != NULL) pw = getpwnam (cp); if (pw == NULL) pw = getpwuid (getuid ()); if (pw != NULL) { char *buf = malloc (strlen (pw->pw_dir) + 1); if (buf) { strcpy (buf, pw->pw_dir); home = buf; } } if (argc > 0) { char *xargv[5]; if (setjmp (toplevel)) exit (EXIT_SUCCESS); signal (SIGINT, intr); signal (SIGPIPE, lostpeer); xargv[0] = program_invocation_name; xargv[1] = argv[0]; xargv[2] = argv[1]; xargv[3] = argv[2]; xargv[4] = NULL; setpeer (argc + 1, xargv); } top = setjmp (toplevel) == 0; if (top) { signal (SIGINT, intr); signal (SIGPIPE, lostpeer); } for (;;) { cmdscanner (top); top = 1; } }
int main (int argc, char *argv[], char **envp) { int index; set_program_name (argv[0]); #ifdef HAVE_TZSET tzset (); /* In case no timezone database in ~ftp. */ #endif #ifdef HAVE_INITSETPROCTITLE /* Save start and extent of argv for setproctitle. */ initsetproctitle (argc, argv, envp); #endif /* HAVE_INITSETPROCTITLE */ /* Parse the command line */ iu_argp_init ("ftpd", default_program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); /* Bail out, wrong usage */ argc -= index; if (argc != 0) error (1, 0, "surplus arguments; try `%s --help' for more info", program_name); /* LOG_NDELAY sets up the logging connection immediately, necessary for anonymous ftp's that chroot and can't do it later. */ openlog ("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); freopen (PATH_DEVNULL, "w", stderr); /* If not running via inetd, we detach and dup(fd, 0), dup(fd, 1) the fd = accept(). tcpd is check if compile with the support */ if (daemon_mode) { if (server_mode (pid_file, &his_addr) < 0) exit (1); } else { socklen_t addrlen = sizeof (his_addr); if (getpeername (STDIN_FILENO, (struct sockaddr *) &his_addr, &addrlen) < 0) { syslog (LOG_ERR, "getpeername (%s): %m", program_name); exit (1); } } signal (SIGHUP, sigquit); signal (SIGINT, sigquit); signal (SIGQUIT, sigquit); signal (SIGTERM, sigquit); signal (SIGPIPE, lostconn); signal (SIGCHLD, SIG_IGN); if (signal (SIGURG, myoob) == SIG_ERR) syslog (LOG_ERR, "signal: %m"); /* Get info on the ctrl connection. */ { socklen_t addrlen = sizeof (ctrl_addr); if (getsockname (STDIN_FILENO, (struct sockaddr *) &ctrl_addr, &addrlen) < 0) { syslog (LOG_ERR, "getsockname (%s): %m", program_name); exit (1); } } #if defined (IP_TOS) && defined (IPTOS_LOWDELAY) && defined (IPPROTO_IP) /* To minimize delays for interactive traffic. */ { int tos = IPTOS_LOWDELAY; if (setsockopt (STDIN_FILENO, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int)) < 0) syslog (LOG_WARNING, "setsockopt (IP_TOS): %m"); } #endif #ifdef SO_OOBINLINE /* Try to handle urgent data inline. */ { int on = 1; if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof (on)) < 0) syslog (LOG_ERR, "setsockopt: %m"); } #endif #ifdef SO_KEEPALIVE /* Set keepalives on the socket to detect dropped connections. */ { int keepalive = 1; if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, (char *) &keepalive, sizeof (keepalive)) < 0) syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); } #endif #ifdef F_SETOWN if (fcntl (STDIN_FILENO, F_SETOWN, getpid ()) == -1) syslog (LOG_ERR, "fcntl F_SETOWN: %m"); #endif dolog (&his_addr, &cred); /* Deal with login disable. */ if (display_file (PATH_NOLOGIN, 530) == 0) { reply (530, "System not available."); exit (0); } /* Display a Welcome message if exists, N.B. reply(220,) must follow. */ display_file (PATH_FTPWELCOME, 220); hostname = localhost (); if (!hostname) perror_reply (550, "Local resource failure: malloc"); /* Tell them we're ready to roll. */ if (!no_version) reply (220, "%s FTP server (%s %s) ready.", hostname, PACKAGE_NAME, PACKAGE_VERSION); else reply (220, "%s FTP server ready.", hostname); /* Set the jump, if we have an error parsing, come here and start fresh. */ setjmp (errcatch); /* Roll. */ for (;;) yyparse (); }
int main (int argc, char *argv[]) { int index; char *fstring; char *qstring; char *p; set_program_name (argv[0]); #ifdef ENABLE_NLS setlocale (LC_MESSAGES, ""); bindtextdomain (NLS_CAT_NAME, LOCALEDIR); textdomain (NLS_CAT_NAME); #endif obstack_init (&query_stk); iu_argp_init ("whois", program_authors); argp_parse (&gwhois_argp, argc, argv, ARGP_IN_ORDER, &index, NULL); obstack_1grow (&query_stk, 0); fstring = obstack_finish (&query_stk); argc -= index; argv += index; if (argc == 0 && !nopar) /* there is no parameter */ error (EXIT_FAILURE, 0, "not enough arguments"); /* parse other parameters, if any */ if (!nopar) { while (argc--) { const char *arg = *argv++; obstack_grow (&query_stk, arg, strlen (arg)); if (argc) obstack_1grow (&query_stk, ' '); } } obstack_1grow (&query_stk, 0); qstring = obstack_finish (&query_stk); if (!server && domfind (qstring, gtlds)) { if (verb) puts (_("Connecting to whois.internic.net.")); sockfd = openconn ("whois.internic.net", NULL); server = query_crsnic (sockfd, qstring); closeconn (sockfd); if (!server) exit (EXIT_SUCCESS); printf (_("\nFound InterNIC referral to %s.\n\n"), server); } if (!server) { server = whichwhois (qstring); switch (server[0]) { case 0: if (!(server = getenv ("WHOIS_SERVER"))) server = DEFAULTSERVER; if (verb) printf (_("Using default server %s.\n"), server); break; case 1: puts (_("This TLD has no whois server, but you can access the " "whois database at")); case 2: puts (server + 1); exit (EXIT_SUCCESS); case 3: puts (_("This TLD has no whois server.")); exit (EXIT_SUCCESS); default: if (verb) printf (_("Using server %s.\n"), server); } } if (getenv ("WHOIS_HIDE")) hide_discl = 0; p = queryformat (server, fstring, qstring); if (verb) printf (_("Query string: \"%s\"\n\n"), p); strcat (p, "\r\n"); signal (SIGTERM, sighandler); signal (SIGINT, sighandler); sockfd = openconn (server, port); do_query (sockfd, p); closeconn (sockfd); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int index; register struct tftphdr *tp; int on, n; struct sockaddr_in sin; set_program_name (argv[0]); iu_argp_init ("tftpd", default_program_authors); argp_parse (&argp, argc, argv, 0, &index, NULL); openlog ("tftpd", LOG_PID, LOG_FTP); if (index < argc) { struct dirlist *dirp; /* Get list of directory prefixes. Skip relative pathnames. */ for (dirp = dirs; index < argc && dirp < &dirs[MAXDIRS]; index++) { if (argv[index][0] == '/') { dirp->name = argv[index]; dirp->len = strlen (dirp->name); dirp++; } } } on = 1; if (ioctl (0, FIONBIO, &on) < 0) { syslog (LOG_ERR, "ioctl(FIONBIO): %m\n"); exit (1); } fromlen = sizeof (from); n = recvfrom (0, buf, sizeof (buf), 0, (struct sockaddr *) &from, &fromlen); if (n < 0) { syslog (LOG_ERR, "recvfrom: %m\n"); exit (1); } /* * Now that we have read the message out of the UDP * socket, we fork and exit. Thus, inetd will go back * to listening to the tftp port, and the next request * to come in will start up a new instance of tftpd. * * We do this so that inetd can run tftpd in "wait" mode. * The problem with tftpd running in "nowait" mode is that * inetd may get one or more successful "selects" on the * tftp port before we do our receive, so more than one * instance of tftpd may be started up. Worse, if tftpd * break before doing the above "recvfrom", inetd would * spawn endless instances, clogging the system. */ { int pid; int i; socklen_t j; for (i = 1; i < 20; i++) { pid = fork (); if (pid < 0) { sleep (i); /* * flush out to most recently sent request. * * This may drop some request, but those * will be resent by the clients when * they timeout. The positive effect of * this flush is to (try to) prevent more * than one tftpd being started up to service * a single request from a single client. */ j = sizeof from; i = recvfrom (0, buf, sizeof (buf), 0, (struct sockaddr *) &from, &j); if (i > 0) { n = i; fromlen = j; } } else { break; } } if (pid < 0) { syslog (LOG_ERR, "fork: %m\n"); exit (1); } else if (pid != 0) { exit (0); } } from.sin_family = AF_INET; alarm (0); close (0); close (1); peer = socket (AF_INET, SOCK_DGRAM, 0); if (peer < 0) { syslog (LOG_ERR, "socket: %m\n"); exit (1); } memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; if (bind (peer, (struct sockaddr *) &sin, sizeof (sin)) < 0) { syslog (LOG_ERR, "bind: %m\n"); exit (1); } if (connect (peer, (struct sockaddr *) &from, sizeof (from)) < 0) { syslog (LOG_ERR, "connect: %m\n"); exit (1); } tp = (struct tftphdr *) buf; tp->th_opcode = ntohs (tp->th_opcode); if (tp->th_opcode == RRQ || tp->th_opcode == WRQ) tftp (tp, n); exit (1); }