/* Present a message on a port */
#include "os.h"
void watch (int port, char *text);
void wave (SOCKET sock, char *text);
int new_connection (SOCKET s);
int init_socket (int port);
int write_to_descriptor (SOCKET desc, char *txt);
void nonblock (SOCKET s);
int main (int argc, char **argv)
{
int port;
char txt[2048], buf[83];
FILE *fl;
if (argc != 3) {
fputs ("Usage: sign (<filename> | - ) <port #>\n", stderr);
exit (1);
}
if (!strcmp (argv[1], "-")) {
fl = stdin;
puts ("Input text (terminate with ^D)");
} else if (!(fl = fopen (argv[1], "rb"))) {
perror (argv[1]);
exit (1);
}
for (;;) {
FGETS (buf, 81, fl);
if (feof (fl))
break;
strcat (buf, "\r");
if (strlen (buf) + strlen (txt) > 2048) {
fputs ("String too long\n", stderr);
exit (1);
}
strcat (txt, buf);
}
if ((port = atoi (argv[2])) <= 1024) {
fputs ("Illegal port #\n", stderr);
exit (1);
}
WIN32STARTUP
watch (port, txt);
WIN32CLEANUP
return 0;
}
void watch (int port, char *text)
{
SOCKET mother;
fd_set input_set;
mother = init_socket (port);
FD_ZERO (&input_set);
for (;;) {
FD_SET (mother, &input_set);
if (select (64, &input_set, 0, 0, 0) < 0) {
perror ("select");
WIN32CLEANUP
exit (1);
}
if (FD_ISSET (mother, &input_set))
wave (mother, text);
}
}
void wave (SOCKET sock, char *text)
{
int s;
if ((s = new_connection (sock)) < 0)
return;
write_to_descriptor (s, text);
#if defined WIN32
Sleep (6000);
#else
sleep (6);
#endif
close (s);
}
int new_connection (SOCKET s)
{
struct sockaddr_in isa;
/* struct sockaddr peer; */
#ifdef WIN32
int i;
#else
socklen_t i;
#endif
int t;
char buf[100];
i = sizeof (isa);
getsockname (s, (struct sockaddr*)&isa, &i);
if ((t = accept (s, (struct sockaddr*)&isa, &i)) < 0) {
perror ("Accept");
return (-1);
}
nonblock (t);
/*
i = sizeof(peer);
if (!getpeername(t, &peer, &i))
{
*(peer.sa_data + 49) = '\0';
sprintf(buf, "New connection from addr %s\n", peer.sa_data);
log(buf);
}
*/
return (t);
}
int init_socket (int port)
{
SOCKET s;
char *opt;
char hostname[1024];
struct sockaddr_in sa;
struct hostent *hp;
struct linger ld;
bzero (&sa, sizeof (struct sockaddr_in));
gethostname (hostname, 1023);
hp = gethostbyname (hostname);
if (hp == NULL) {
perror ("gethostbyname");
exit (1);
}
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons ((unsigned short) port);
s = socket (AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
perror ("Init-socket");
exit (1);
}
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR,
(char *) &opt, sizeof (opt)) < 0) {
perror ("setsockopt REUSEADDR");
exit (1);
}
ld.l_onoff = 1;
ld.l_linger = 1000;
if (setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof (ld)) < 0) {
perror ("setsockopt LINGER");
exit (1);
}
if (bind (s, (struct sockaddr*)&sa, sizeof (sa)) < 0) {
perror ("bind");
close (s);
exit (1);
}
listen (s, 5);
return (s);
}
int write_to_descriptor (SOCKET desc, char *txt)
{
int sofar, thisround, total;
total = strlen (txt);
sofar = 0;
do {
thisround = send (desc, txt + sofar, total - sofar, 0);
if (thisround < 0) {
perror ("Write to socket");
return (-1);
}
sofar += thisround;
}
while (sofar < total);
return (0);
}
void nonblock (SOCKET s)
{
#ifdef WIN32
unsigned long flags = 1;
if (ioctlsocket (s, FIONBIO, &flags)) {
#else
if (fcntl (s, F_SETFL, FNDELAY) == -1) {
#endif
perror ("Noblock");
exit (1);
}
}