date and time created 84/04/11 15:02:40 by karels
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Thu, 12 Apr 1984 06:02:40 +0000 (22:02 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Thu, 12 Apr 1984 06:02:40 +0000 (22:02 -0800)
SCCS-vsn: libexec/talkd/announce.c 1.1

usr/src/libexec/talkd/announce.c [new file with mode: 0644]

diff --git a/usr/src/libexec/talkd/announce.c b/usr/src/libexec/talkd/announce.c
new file mode 100644 (file)
index 0000000..74baa18
--- /dev/null
@@ -0,0 +1,208 @@
+/* $Header: /a/guest/moore/talk/RCS/announce.c,v 1.8 83/07/06 00:16:57 moore Exp $ */
+
+#include "ctl.h"
+
+#include <sys/stat.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+char *sprintf();
+
+extern int errno;
+extern char hostname[];
+int nofork = 0;                /* to be set from the debugger */
+
+/*
+ * Because the tty driver insists on attaching a terminal-less
+ * process to any terminal that it writes on, we must fork a child
+ * to protect ourselves
+ */
+
+announce(request, remote_machine)
+CTL_MSG *request;
+char *remote_machine;
+{
+    int pid, val, status;
+
+    if (nofork) {
+       return(announce_proc(request, remote_machine));
+    }
+
+    if ( pid = fork() ) {
+
+           /* we are the parent, so wait for the child */
+
+       if (pid == -1) {
+               /* the fork failed */
+           return(FAILED);
+       }
+
+       do {
+           val = wait(&status);
+           if (val == -1) {
+               if (errno == EINTR) {
+                   continue;
+               } else {
+                       /* shouldn't happen */
+                   print_error("wait");
+                   return(FAILED);
+               }
+           }
+       } while (val != pid);
+
+       if (status&0377 > 0) {
+               /* we were killed by some signal */
+           return(FAILED);
+       }
+
+           /* Get the second byte, this is the exit/return code */
+
+       return((status>>8)&0377);
+
+    } else {
+           /* we are the child, go and do it */
+       _exit(announce_proc(request, remote_machine));
+    }
+}
+       
+
+    /* See if the user is accepting messages. If so, announce that 
+       a talk is requested.
+     */
+
+announce_proc(request, remote_machine)
+CTL_MSG *request;
+char *remote_machine;
+{
+    int pid, status;
+    char full_tty[32];
+    FILE *tf;
+    struct stat stbuf;
+
+
+    (void) sprintf(full_tty, "/dev/%s", request->r_tty);
+
+    if (access(full_tty, 0) != 0) {
+       return(FAILED);
+    }
+
+    if ((tf = fopen(full_tty, "w")) == NULL) {
+       return(PERMISSION_DENIED);
+    }
+
+       /* open gratuitously attaches the talkd to
+          any tty it opens, so disconnect us from the
+          tty before we catch a signal */
+
+    ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
+
+    if (fstat(fileno(tf), &stbuf) < 0) {
+       return(PERMISSION_DENIED);
+    }
+
+    if ((stbuf.st_mode&02) == 0) {
+       return(PERMISSION_DENIED);
+    }
+
+    print_mesg(tf, request, remote_machine);
+    fclose(tf);
+    return(SUCCESS);
+}
+
+#define max(a,b) ( (a) > (b) ? (a) : (b) )
+#define N_LINES 5
+#define N_CHARS 120
+
+    /*
+     * build a block of characters containing the message. 
+     * It is sent blank filled and in a single block to
+     * try to keep the message in one piece if the recipient
+     * in in vi at the time
+     */
+
+print_mesg(tf, request, remote_machine)
+FILE *tf;
+CTL_MSG *request;
+char *remote_machine;
+{
+    struct timeval clock;
+    struct timezone zone;
+    struct tm *localtime();
+    struct tm *localclock;
+    char line_buf[N_LINES][N_CHARS];
+    int sizes[N_LINES];
+    char big_buf[N_LINES*N_CHARS];
+    char *bptr, *lptr;
+    int i, j, max_size;
+
+    i = 0;
+    max_size = 0;
+
+    gettimeofday(&clock, &zone);
+    localclock = localtime( &clock.tv_sec );
+
+    sprintf(line_buf[i], " ");
+
+    sizes[i] = strlen(line_buf[i]);
+    max_size = max(max_size, sizes[i]);
+    i++;
+
+    sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
+       hostname, localclock->tm_hour , localclock->tm_min );
+
+    sizes[i] = strlen(line_buf[i]);
+    max_size = max(max_size, sizes[i]);
+    i++;
+
+    sprintf(line_buf[i], "talk: connection requested by %s@%s.",
+               request->l_name, remote_machine);
+
+    sizes[i] = strlen(line_buf[i]);
+    max_size = max(max_size, sizes[i]);
+    i++;
+
+    sprintf(line_buf[i], "talk: respond with:  talk %s@%s",
+               request->l_name, remote_machine);
+
+    sizes[i] = strlen(line_buf[i]);
+    max_size = max(max_size, sizes[i]);
+    i++;
+
+    sprintf(line_buf[i], " ");
+
+    sizes[i] = strlen(line_buf[i]);
+    max_size = max(max_size, sizes[i]);
+    i++;
+
+    bptr = big_buf;
+    *(bptr++) = '\a';   /* send something to wake them up */
+    *(bptr++) = '\r';  /* add a \r in case of raw mode */
+    *(bptr++) = '\n';
+    for(i = 0; i < N_LINES; i++) {
+
+           /* copy the line into the big buffer */
+
+       lptr = line_buf[i];
+       while (*lptr != '\0') {
+           *(bptr++) = *(lptr++);
+       }
+
+           /* pad out the rest of the lines with blanks */
+
+       for(j = sizes[i]; j < max_size + 2; j++) {
+           *(bptr++) = ' ';
+       }
+
+       *(bptr++) = '\r';       /* add a \r in case of raw mode */
+       *(bptr++) = '\n';
+    }
+    *bptr = '\0';
+
+    fprintf(tf, big_buf);
+    fflush(tf);
+    ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
+}