1: #if !defined(lint) && defined(DOSCCS)
   2: static char *sccsid = "@(#)write.c	4.13.2 1996/11/16";
   3: #endif
   4: /*
   5:  * write to another user
   6:  */
   7: 
   8: #include <stdio.h>
   9: #include <ctype.h>
  10: #include <sys/types.h>
  11: #include <sys/stat.h>
  12: #include <signal.h>
  13: #include <utmp.h>
  14: #include <errno.h>
  15: #include <string.h>
  16: #include <unistd.h>
  17: #include <stdlib.h>
  18: #include <time.h>
  19: 
  20: #define NMAX    sizeof(ubuf.ut_name)
  21: #define LMAX    sizeof(ubuf.ut_line)
  22: 
  23: struct  utmp ubuf;
  24: int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
  25: char    me[NMAX + 1]    = "???";
  26: char    *him;
  27: char    *mytty;
  28: char    histty[32];
  29: char    ttybuf[32];
  30: char    *histtya;
  31: int logcnt;
  32: int eof();
  33: int timout();
  34: FILE    *tf;
  35: 
  36: main(argc, argv)
  37:     int argc;
  38:     char *argv[];
  39: {
  40:     struct stat stbuf;
  41:     register i;
  42:     register FILE *uf;
  43:     int c1, c2;
  44:     time_t clock = time(0);
  45:     int suser = getuid() == 0;
  46:     int nomesg = 0;
  47:     struct tm *localclock = localtime( &clock );
  48: 
  49:     if (argc < 2) {
  50:         fprintf(stderr, "Usage: write user [ttyname]\n");
  51:         exit(1);
  52:     }
  53:     him = argv[1];
  54:     if (argc > 2)
  55:         histtya = argv[2];
  56:     if ((uf = fopen(_PATH_UTMP, "r")) == NULL) {
  57:         fprintf(stderr, "write: %s: %s\n", _PATH_UTMP, strerror(errno));
  58:         if (histtya == 0)
  59:             exit(10);
  60:         goto cont;
  61:     }
  62:     mytty = ttyname(2);
  63:     if (mytty == NULL) {
  64:         fprintf(stderr, "write: Can't find your tty\n");
  65:         exit(1);
  66:     }
  67:     if (stat(mytty, &stbuf) < 0) {
  68:         perror("write: Can't stat your tty");
  69:         exit(1);
  70:     }
  71:     if ((stbuf.st_mode&020) == 0) {
  72:         fprintf(stderr,
  73:             "write: You have write permission turned off\n");
  74:         if (!suser)
  75:             exit(1);
  76:     }
  77:     mytty = rindex(mytty, '/') + 1;
  78:     if (histtya) {
  79:         strcpy(histty, "/dev/");
  80:         strcat(histty, histtya);
  81:     }
  82:     while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) {
  83:         if (ubuf.ut_name[0] == '\0')
  84:             continue;
  85:         if (strcmp(ubuf.ut_line, mytty)==0) {
  86:             for (i=0; i<NMAX; i++) {
  87:                 c1 = ubuf.ut_name[i];
  88:                 if (c1 == ' ')
  89:                     c1 = 0;
  90:                 me[i] = c1;
  91:                 if (c1 == 0)
  92:                     break;
  93:             }
  94:         }
  95:         if (him[0] == '-' && him[1] == 0)
  96:             goto nomat;
  97:         for (i=0; i<NMAX; i++) {
  98:             c1 = him[i];
  99:             c2 = ubuf.ut_name[i];
 100:             if (c1 == 0)
 101:                 if (c2 == 0 || c2 == ' ')
 102:                     break;
 103:             if (c1 != c2)
 104:                 goto nomat;
 105:         }
 106:         if (histtya && strncmp(histtya, ubuf.ut_line,
 107:             sizeof(ubuf.ut_line)))
 108:             continue;
 109:         logcnt++;
 110:         if (histty[0]==0 || nomesg && histtya == 0) {
 111:             strcpy(ttybuf, "/dev/");
 112:             strcat(ttybuf, ubuf.ut_line);
 113:             if (histty[0]==0)
 114:                 strcpy(histty, ttybuf);
 115:             if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 ||
 116:                 (stbuf.st_mode&020) == 0)
 117:                 nomesg++;
 118:             else {
 119:                 strcpy(histty, ttybuf);
 120:                 nomesg = 0;
 121:             }
 122:         }
 123:     nomat:
 124:         ;
 125:     }
 126:     fclose(uf);
 127:     if (logcnt==0) {
 128:         fprintf(stderr, "write: %s not logged in%s\n", him,
 129:             histtya ? " on that tty" : "");
 130:         exit(1);
 131:     }
 132:     if (histtya==0 && logcnt > 1) {
 133:         fprintf(stderr,
 134:         "write: %s logged in more than once ... writing to %s\n",
 135:             him, histty+5);
 136:     }
 137: cont:
 138:     if (access(histty, 0) < 0) {
 139:         fprintf(stderr, "write: No such tty\n");
 140:         exit(1);
 141:     }
 142:     signal(SIGALRM, timout);
 143:     alarm(5);
 144:     if ((tf = fopen(histty, "w")) == NULL) {
 145:         fprintf(stderr, "write: Permission denied\n");
 146:         exit(1);
 147:     }
 148:     alarm(0);
 149:     sigs(eof);
 150:     { char hostname[32];
 151:       gethostname(hostname, sizeof (hostname));
 152:       fprintf(tf,
 153:           "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007",
 154:           me, hostname, mytty, localclock->tm_hour, localclock->tm_min);
 155:     fflush(tf);
 156:     }
 157:     for (;;) {
 158:         char buf[BUFSIZ];
 159:         register char *bp;
 160:         i = read(0, buf, sizeof buf);
 161:         if (i <= 0)
 162:             eof();
 163:         if (buf[0] == '!') {
 164:             buf[i] = 0;
 165:             ex(buf);
 166:             continue;
 167:         }
 168:         for (bp = buf; --i >= 0; bp++) {
 169:             if (*bp == '\n')
 170:                 putc('\r', tf);
 171: 
 172:             if (!isascii(*bp)) {
 173:                 putc('M', tf);
 174:                 putc('-', tf);
 175:                 *bp = toascii(*bp);
 176:             }
 177: 
 178:             if (isprint(*bp) ||
 179:                 *bp == ' ' || *bp == '\t' || *bp == '\n') {
 180:                 putc(*bp, tf);
 181:             } else {
 182:                 putc('^', tf);
 183:                 putc(*bp ^ 0100, tf);
 184:             }
 185: 
 186:             if (*bp == '\n')
 187:                 fflush(tf);
 188: 
 189:             if (ferror(tf) || feof(tf)) {
 190:                 printf("\n\007Write failed (%s logged out?)\n",
 191:                     him);
 192:                 exit(1);
 193:             }
 194:         }
 195:     }
 196: }
 197: 
 198: timout()
 199: {
 200: 
 201:     fprintf(stderr, "write: Timeout opening their tty\n");
 202:     exit(1);
 203: }
 204: 
 205: eof()
 206: {
 207: 
 208:     fprintf(tf, "EOF\r\n");
 209:     exit(0);
 210: }
 211: 
 212: ex(bp)
 213:     char *bp;
 214: {
 215:     register i;
 216: 
 217:     sigs(SIG_IGN);
 218:     i = fork();
 219:     if (i < 0) {
 220:         printf("Try again\n");
 221:         goto out;
 222:     }
 223:     if (i == 0) {
 224:         fclose(tf);     /* Close his terminal */
 225:         setgid(getgid());   /* Give up effective group privs */
 226:         sigs((int (*)())0);
 227:         execl(getenv("SHELL") ?
 228:             getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
 229:         exit(0);
 230:     }
 231:     while (wait((int *)NULL) != i)
 232:         ;
 233:     printf("!\n");
 234: out:
 235:     sigs(eof);
 236: }
 237: 
 238: sigs(sig)
 239:     int (*sig)();
 240: {
 241:     register i;
 242: 
 243:     for (i=0; signum[i]; i++)
 244:         signal(signum[i], sig);
 245: }

Defined functions

eof defined in line 205; used 4 times
ex defined in line 212; used 1 times
main defined in line 36; never used
sigs defined in line 238; used 4 times
timout defined in line 198; used 2 times

Defined variables

him defined in line 26; used 7 times
histty defined in line 28; used 9 times
histtya defined in line 30; used 9 times
logcnt defined in line 31; used 3 times
me defined in line 25; used 2 times
mytty defined in line 27; used 7 times
sccsid defined in line 2; never used
signum defined in line 24; used 2 times
ttybuf defined in line 29; used 6 times
ubuf defined in line 23; used 11 times

Defined macros

LMAX defined in line 21; never used
NMAX defined in line 20; used 3 times
Last modified: 1996-11-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 981
Valid CSS Valid XHTML 1.0 Strict