📄 inetd.c
字号:
else sep->se_type = MUX_TYPE; sep->se_service = newstr (c); } else { sep->se_service = newstr (arg); sep->se_type = NORM_TYPE; } arg = sskip (&cp, fconfig, file); if (strcmp (arg, "stream") == 0) sep->se_socktype = SOCK_STREAM; else if (strcmp (arg, "dgram") == 0) sep->se_socktype = SOCK_DGRAM; else if (strcmp (arg, "rdm") == 0) sep->se_socktype = SOCK_RDM; else if (strcmp (arg, "seqpacket") == 0) sep->se_socktype = SOCK_SEQPACKET; else if (strcmp (arg, "raw") == 0) sep->se_socktype = SOCK_RAW; else sep->se_socktype = -1; sep->se_proto = newstr (sskip (&cp, fconfig, file)); arg = sskip (&cp, fconfig, file); sep->se_wait = strcmp (arg, "wait") == 0; if (ISMUX (sep)) { /* * Silently enforce "nowait" for TCPMUX services since * they don't have an assigned port to listen on. */ sep->se_wait = 0; if (strcmp (sep->se_proto, "tcp")) { syslog (LOG_ERR, "%s: bad protocol for tcpmux service %s", file, sep->se_service); goto more; } if (sep->se_socktype != SOCK_STREAM) { syslog (LOG_ERR, "%s: bad socket type for tcpmux service %s", file, sep->se_service); goto more; } } sep->se_user = newstr (sskip (&cp, fconfig, file)); sep->se_server = newstr (sskip (&cp, fconfig, file)); if (strcmp (sep->se_server, "internal") == 0) { struct biltin *bi; for (bi = biltins; bi->bi_service; bi++) if (bi->bi_socktype == sep->se_socktype && strcmp (bi->bi_service, sep->se_service) == 0) break; if (bi->bi_service == 0) { syslog (LOG_ERR, "internal service %s unknown", sep->se_service); goto more; } sep->se_bi = bi; sep->se_wait = bi->bi_wait; } else sep->se_bi = NULL; argc = 0; for (arg = skip (&cp, fconfig); cp; arg = skip (&cp, fconfig)) if (argc < MAXARGV) sep->se_argv[argc++] = newstr (arg); while (argc <= MAXARGV) sep->se_argv[argc++] = NULL; return sep;}voidfreeconfig (struct servtab *cp){ int i; if (cp->se_service) free (cp->se_service); if (cp->se_proto) free (cp->se_proto); if (cp->se_user) free (cp->se_user); if (cp->se_server) free (cp->se_server); for (i = 0; i < MAXARGV; i++) if (cp->se_argv[i]) free (cp->se_argv[i]);}/* * Safe skip - if skip returns null, log a syntax error in the * configuration file and exit. */char *sskip (char **cpp, FILE *fconfig, const char *file){ char *cp; cp = skip (cpp, fconfig); if (cp == NULL) { syslog (LOG_ERR, "%s: syntax error", file); exit(-1); } return cp;}char *skip (char **cpp, FILE *fconfig){ char *cp = *cpp; char *start;again: while (*cp == ' ' || *cp == '\t') cp++; if (*cp == '\0') { int c; c = getc (fconfig); (void) ungetc (c, fconfig); if (c == ' ' || c == '\t') if ((cp = nextline (fconfig))) goto again; *cpp = (char *)0; return ((char *)0); } start = cp; while (*cp && *cp != ' ' && *cp != '\t') cp++; if (*cp != '\0') *cp++ = '\0'; *cpp = cp; return start;}char *nextline (FILE *fd){ char *cp; if (fgets (line, sizeof line, fd) == NULL) return ((char *)0); cp = strchr (line, '\n'); if (cp) *cp = '\0'; return line;}char *newstr (const char *cp){ char *s; if ((s = strdup (cp ? cp : ""))) return s; syslog (LOG_ERR, "strdup: %m"); exit (-1);}voidset_proc_title (char *a, int s){ int size; char *cp; struct sockaddr_in lsin; char buf[80]; cp = Argv[0]; size = sizeof lsin; if (getpeername (s, (struct sockaddr *)&lsin, &size) == 0) snprintf (buf, sizeof buf, "-%s [%s]", a, inet_ntoa (lsin.sin_addr)); else snprintf (buf, sizeof buf, "-%s", a); strncpy (cp, buf, LastArg - cp); cp += strlen (cp); while (cp < LastArg) *cp++ = ' ';}/* * Internet services provided internally by inetd: */#define BUFSIZE 8192/* ARGSUSED *//* Echo service -- echo data back */voidecho_stream (int s, struct servtab *sep){ char buffer[BUFSIZE]; int i; set_proc_title (sep->se_service, s); while ((i = read (s, buffer, sizeof buffer)) > 0 && write (s, buffer, i) > 0) ; exit (0);}/* ARGSUSED *//* Echo service -- echo data back */voidecho_dg (int s, struct servtab *sep){ char buffer[BUFSIZE]; int i, size; struct sockaddr sa; (void)sep; size = sizeof sa; if ((i = recvfrom (s, buffer, sizeof buffer, 0, &sa, &size)) < 0) return; (void) sendto (s, buffer, i, 0, &sa, sizeof sa);}/* ARGSUSED *//* Discard service -- ignore data */voiddiscard_stream (int s, struct servtab *sep){ int ret; char buffer[BUFSIZE]; set_proc_title (sep->se_service, s); while (1) { while ((ret = read (s, buffer, sizeof buffer)) > 0) ; if (ret == 0 || errno != EINTR) break; } exit (0);}/* ARGSUSED */void/* Discard service -- ignore data */discard_dg (int s, struct servtab *sep){ char buffer[BUFSIZE]; (void)sep; /* shutup gcc */ (void) read (s, buffer, sizeof buffer);}#include <ctype.h>#define LINESIZ 72char ring[128];char *endring;voidinitring (void){ int i; endring = ring; for (i = 0; i <= 128; ++i) if (isprint (i)) *endring++ = i;}/* ARGSUSED *//* Character generator */voidchargen_stream (int s, struct servtab *sep){ int len; char *rs, text[LINESIZ+2]; set_proc_title (sep->se_service, s); if (!endring) { initring (); rs = ring; } text[LINESIZ] = '\r'; text[LINESIZ + 1] = '\n'; for (rs = ring;;) { if ((len = endring - rs) >= LINESIZ) memmove (text, rs, LINESIZ); else { memmove (text, rs, len); memmove (text + len, ring, LINESIZ - len); } if (++rs == endring) rs = ring; if (write (s, text, sizeof text) != sizeof text) break; } exit (0);}/* ARGSUSED *//* Character generator */voidchargen_dg (int s, struct servtab *sep){ struct sockaddr sa; static char *rs; int len, size; char text[LINESIZ+2]; (void)sep; /* shutup gcc */ if (endring == 0) { initring (); rs = ring; } size = sizeof sa; if (recvfrom (s, text, sizeof text, 0, &sa, &size) < 0) return; if ((len = endring - rs) >= LINESIZ) memmove (text, rs, LINESIZ); else { memmove (text, rs, len); memmove (text + len, ring, LINESIZ - len); } if (++rs == endring) rs = ring; text[LINESIZ] = '\r'; text[LINESIZ + 1] = '\n'; (void) sendto (s, text, sizeof text, 0, &sa, sizeof sa);}/* * Return a machine readable date and time, in the form of the * number of seconds since midnight, Jan 1, 1900. Since gettimeofday * returns the number of seconds since midnight, Jan 1, 1970, * we must add 2208988800 seconds to this figure to make up for * some seventy years Bell Labs was asleep. */longmachtime (void){ struct timeval tv; if (gettimeofday (&tv, (struct timezone *)0) < 0) { if (debug) fprintf (stderr, "Unable to get time of day\n"); return 0L; }#define OFFSET ((u_long)25567 * 24*60*60) return (htonl ((long)(tv.tv_sec + OFFSET)));#undef OFFSET}/* ARGSUSED */voidmachtime_stream (int s, struct servtab *sep){ long result; (void)sep; /* shutup gcc */ result = machtime (); (void) write (s, (char *) &result, sizeof result);}/* ARGSUSED */voidmachtime_dg (int s, struct servtab *sep){ long result; struct sockaddr sa; int size; (void)sep; /* shutup gcc */ size = sizeof sa; if (recvfrom (s, (char *)&result, sizeof result, 0, &sa, &size) < 0) return; result = machtime (); (void) sendto (s, (char *) &result, sizeof result, 0, &sa, sizeof sa);}/* ARGSUSED */void/* Return human-readable time of day */daytime_stream (int s, struct servtab *sep){ char buffer[256]; time_t lclock; (void)sep; /*shutup gcc*/ lclock = time ((time_t *) 0); (void) sprintf (buffer, "%.24s\r\n", ctime(&lclock)); (void) write (s, buffer, strlen(buffer));}/* ARGSUSED *//* Return human-readable time of day */voiddaytime_dg(int s, struct servtab *sep){ char buffer[256]; time_t lclock; struct sockaddr sa; int size; (void)sep; /* shutup gcc */ lclock = time ((time_t *) 0); size = sizeof sa; if (recvfrom (s, buffer, sizeof buffer, 0, &sa, &size) < 0) return; (void) sprintf (buffer, "%.24s\r\n", ctime (&lclock)); (void) sendto (s, buffer, strlen(buffer), 0, &sa, sizeof sa);}/* * print_service: * Dump relevant information to stderr */voidprint_service (const char *file, const char *action, struct servtab *sep){ fprintf (stderr, "%s:%s: %s proto=%s, wait=%d, user=%s builtin=%lx server=%s\n", file, action, sep->se_service, sep->se_proto, sep->se_wait, sep->se_user, (long)sep->se_bi, sep->se_server);}/* * Based on TCPMUX.C by Mark K. Lottor November 1988 * sri-nic::ps:<mkl>tcpmux.c *//* # of characters upto \r,\n or \0 */static intfd_getline (int fd, char *buf, int len){ int count = 0, n; do { n = read (fd, buf, len-count); if (n == 0) return count; if (n < 0) return -1; while (--n >= 0) { if (*buf == '\r' || *buf == '\n' || *buf == '\0') return count; count++; buf++; } } while (count < len); return count;}#define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */#define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1)voidtcpmux(int s, struct servtab *sep){ char service[MAX_SERV_LEN+1]; int len; /* Get requested service name */ if ((len = fd_getline (s, service, MAX_SERV_LEN)) < 0) { strwrite (s, "-Error reading service name\r\n"); _exit (1); } service[len] = '\0'; if (debug) fprintf (stderr, "tcpmux: someone wants %s\n", service); /* * Help is a required command, and lists available services, * one per line. */ if (!strcasecmp (service, "help")) { for (sep = servtab; sep; sep = sep->se_next) { if (!ISMUX (sep)) continue; (void)write (s, sep->se_service, strlen (sep->se_service)); strwrite (s, "\r\n"); } _exit (1); } /* Try matching a service in inetd.conf with the request */ for (sep = servtab; sep; sep = sep->se_next) { if (!ISMUX (sep)) continue; if (!strcasecmp (service, sep->se_service)) { if (ISMUXPLUS (sep)) { strwrite (s, "+Go\r\n"); } run_service (s, sep); return; } } strwrite (s, "-Service not available\r\n"); exit (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -