/* * announce - sits listening on a port, and whenever anyone connects * announces a message and disconnects them * * Usage: announce [port] < message_file * * Author: Lawrence Brown <lpb@cs.adfa.oz.au> Aug 90 * * Bits of code are adapted from the Berkeley telnetd sources */ #define PORT 4201 #include <sys/param.h> #include <sys/socket.h> #include <sys/time.h> #include <time.h> #include <sys/resource.h> #include <netinet/in.h> #include <netdb.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <unistd.h> #ifdef USE_IPV6 #include <netinet6/in6.h> #endif extern char **environ; #ifdef HAVE_ERRNO_H #include <errno.h> #else #ifdef HAVE_SYS_ERRNO_H #include <sys/errno.h> #else extern int errno; #endif #endif char *Name; /* name of this program for error messages */ char msg[32768]; #ifdef __APPLE__ typedef unsigned int socklen_t; #endif char* strcpyn(char* buf, size_t bufsize, const char* src) { int pos = 0; char* dest = buf; while (++pos < bufsize && *src) { *dest++ = *src++; } *dest = '\0'; return buf; } char* strcatn(char* buf, size_t bufsize, const char* src) { int pos = strlen(buf); char* dest = &buf[pos]; while (++pos < bufsize && *src) { *dest++ = *src++; } if (pos < bufsize + 1) { *dest = '\0'; } return buf; } int notify(int player, const char *msg) { return printf("%s\n", msg); } int main(int argc, char *argv[]) { int s, ns; socklen_t foo; #ifdef USE_IPV6 static struct sockaddr_in6 sin = { AF_INET6 }; char host[128], *inet_ntoa(); #else static struct sockaddr_in sin = { AF_INET }; char *host, *inet_ntoa(); #endif char tmp[32768]; time_t ct; Name = argv[0]; /* save name of program for error messages */ #ifdef USE_IPV6 sin.sin6_port = htons((u_short) PORT); /* Assume PORT */ argc--, argv++; if (argc > 0) { /* unless specified on command-line */ sin.sin6_port = atoi(*argv); sin.sin6_port = htons((u_short) sin.sin6_port); } #else sin.sin_port = htons((u_short) PORT); /* Assume PORT */ argc--, argv++; if (argc > 0) { /* unless specified on command-line */ sin.sin_port = atoi(*argv); sin.sin_port = htons((u_short) sin.sin_port); } #endif strcpyn(msg, sizeof(msg), ""); strcpyn(tmp, sizeof(tmp), ""); while (1) { if (fgets(tmp,32766,stdin) == NULL) break; strcatn(tmp, sizeof(tmp), "\r\n"); strcatn(msg, sizeof(msg), tmp); } msg[4095] = '\0'; signal(SIGHUP, SIG_IGN); /* get socket, bind port to it */ s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("announce: socket"); exit(1); } if (bind(s, (struct sockaddr *) &sin, sizeof sin) < 0) { perror("bind"); exit(1); } if ((foo = fork()) != 0) { #ifdef USE_IPV6 fprintf(stderr, "announce: pid %d running on port %d\n", foo, ntohs((u_short) sin.sin6_port)); #else fprintf(stderr, "announce: pid %d running on port %d\n", foo, ntohs((u_short) sin.sin_port)); #endif _exit(0); } else { #ifdef PRIO_PROCESS setpriority(PRIO_PROCESS, getpid(), 10); #endif } if (listen(s, 1) < 0) { /* start listening on port */ perror("announce: listen"); exit(1); } foo = sizeof sin; for (;;) { /* loop forever, accepting requests & printing * msg */ ns = accept(s, (struct sockaddr *) &sin, &foo); if (ns < 0) { perror("announce: accept"); exit(1); } #ifdef USE_IPV6 inet_ntop(AF_INET6, sin.sin6_addr, host, 128); #else host = inet_ntoa(sin.sin_addr); #endif ct = time((time_t *) NULL); fprintf(stderr, "CONNECTION made from %s at %s", host, ctime(&ct)); write(ns, msg, strlen(msg)); sleep(5); close(ns); } } /* main */