source: trunk/athena/bin/write/write.c @ 6820

Revision 6820, 8.0 KB checked in by vrt, 31 years ago (diff)
Solaris no longer calls setpgrp. (vrt)
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/write/write.c,v $
3 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/write/write.c,v 1.11 1993-07-22 19:31:25 vrt Exp $
4 */
5
6#ifndef lint
7static char *rcsid_write_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/write/write.c,v 1.11 1993-07-22 19:31:25 vrt Exp $";
8#endif lint
9
10#ifndef lint
11static char *sccsid = "@(#)write.c      4.13 3/13/86";
12#endif
13/*
14 * write to another user
15 */
16
17#include <stdio.h>
18#include <ctype.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <signal.h>
22#include <utmp.h>
23#include <time.h>
24#include <sys/time.h>
25#include        <sys/socket.h>
26#include        <netinet/in.h>
27#include        <netdb.h>
28#include <pwd.h>
29
30#define NMAX    sizeof(ubuf.ut_name)
31#define LMAX    sizeof(ubuf.ut_line)
32
33char    *strcat();
34char    *strcpy();
35struct  utmp ubuf;
36int     signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
37char    mebuf[NMAX + 1] = "???";
38char    *me;
39char    *him;
40int     netme = 0;
41int     nethim = 0;
42char    *mytty;
43char    histty[32];
44char    ttybuf[32];
45char    *histtya;
46char    myhost[32];
47char    *hishost;
48struct hostent *hp;
49struct servent *sp;
50struct sockaddr_in sin;
51int     fds;
52char    buf[128];
53struct passwd *pwdent;
54FILE    *tf;
55int     logcnt;
56char    *ttyname();
57char    *rindex();
58int     eof();
59int     timout();
60char    *getenv();
61
62#ifdef _AIX
63#define setpgrp setpgid
64#endif
65
66main(argc, argv)
67        int argc;
68        char *argv[];
69{
70        struct stat stbuf;
71        register i;
72        register FILE *uf;
73        int c1, c2;
74        long clock = time(0);
75        int suser = getuid() == 0;
76        int nomesg = 0;
77        struct tm *localtime();
78        struct tm *localclock = localtime( &clock );
79
80        me = mebuf;
81        if ((argc > 3) && (getuid() == 0) &&
82            (strcmp("-f", argv[1]) == 0) &&
83            (mytty = rindex(argv[2], '@'))) {
84                me = argv[2];
85                *mytty++ = '\0';
86                netme = 1;
87                argc -= 2;
88                argv += 2;
89        }
90        if (argc < 2 || argc > 3) {
91                fprintf(stderr, "Usage: write user [ttyname]\n");
92                exit(1);
93        }
94        him = argv[1];
95        if ((!netme) && (hishost = rindex(him, '@'))) {
96                *hishost++ = '\0';
97                hp = gethostbyname(hishost);
98                if (hp == NULL) {
99                        static struct hostent def;
100                        static struct in_addr defaddr;
101                        static char namebuf[128];
102                        int inet_addr();
103
104                        defaddr.s_addr = inet_addr(hishost);
105                        if (defaddr.s_addr == -1) {
106                                printf("unknown host: %s\n", hishost);
107                                exit(1);
108                        }
109                        strcpy(namebuf, hishost);
110                        def.h_name = namebuf;
111                        def.h_addr = (char *)&defaddr;
112                        def.h_length = sizeof (struct in_addr);
113                        def.h_addrtype = AF_INET;
114                        def.h_aliases = 0;
115                        hp = &def;
116                }
117                nethim = 1;
118        }
119
120        if (argc == 3)
121                histtya = argv[2];
122        if ((uf = fopen("/etc/utmp", "r")) == NULL) {
123                perror("write: Can't open /etc/utmp");
124                if (histtya == 0)
125                        exit(10);
126                goto cont;
127        }
128        if (!netme) {
129            mytty = ttyname(2);
130            if (mytty == NULL) {
131                fprintf(stderr, "write: Can't find your tty\n");
132                exit(1);
133            }
134            if (stat(mytty, &stbuf) < 0) {
135                perror("write: Can't stat your tty");
136                exit(1);
137            }
138            if ((stbuf.st_mode&020) == 0) {
139                fprintf(stderr,
140                        "write: You have write permission turned off\n");
141                if (!suser)
142                  exit(1);
143            }
144            mytty = rindex(mytty, '/') + 1;
145        }
146        if (histtya) {
147                strcpy(histty, "/dev/");
148                strcat(histty, histtya);
149        }
150        while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) {
151                if (ubuf.ut_name[0] == '\0')
152                        continue;
153#if defined(_AIX)
154                if (ubuf.ut_type != USER_PROCESS)
155                        continue;
156#endif
157                if ((!netme) && strcmp(ubuf.ut_line, mytty)==0) {
158                        for (i=0; i<NMAX; i++) {
159                                c1 = ubuf.ut_name[i];
160                                if (c1 == ' ')
161                                        c1 = 0;
162                                me[i] = c1;
163                                if (c1 == 0)
164                                        break;
165                        }
166                }
167                if (nethim) goto nomat;
168                if (him[0] == '-' && him[1] == 0)
169                        goto nomat;
170                for (i=0; i<NMAX; i++) {
171                        c1 = him[i];
172                        c2 = ubuf.ut_name[i];
173                        if (c1 == 0)
174                                if (c2 == 0 || c2 == ' ')
175                                        break;
176                        if (c1 != c2)
177                                goto nomat;
178                }
179                if (histtya && strncmp(histtya, ubuf.ut_line,
180                    sizeof(ubuf.ut_line)))
181                        continue;
182                logcnt++;
183                if (histty[0]==0 || nomesg && histtya == 0) {
184                        strcpy(ttybuf, "/dev/");
185                        strcat(ttybuf, ubuf.ut_line);
186                        if (histty[0]==0)
187                                strcpy(histty, ttybuf);
188                        if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 ||
189                            (stbuf.st_mode&020) == 0)
190                                nomesg++;
191                        else {
192                                strcpy(histty, ttybuf);
193                                nomesg = 0;
194                        }
195                }
196        nomat:
197                ;
198        }
199        fclose(uf);
200        if (!nethim) {
201            if (logcnt==0) {
202                fprintf(stderr, "write: %s not logged in%s\n", him,
203                        histtya ? " on that tty" : "");
204                exit(1);
205            }
206            if (histtya==0 && logcnt > 1) {
207                fprintf(stderr,
208                        "write: %s logged in more than once ... writing to %s\n",
209                        him, histty+5);
210            }
211#ifdef _AIX
212            /* This appears to flush the stderr buffer on the PS/2 so that
213               both sides of the connection don't receive the message.
214               Wierd. - Ezra */
215            fflush(stderr);
216#endif
217        }
218cont:
219        fclose(uf);
220        if((!netme) && (mebuf[0] == '?')) {
221            pwdent = getpwuid(getuid());
222            if (pwdent == NULL) {
223                printf("You don't exist. Go away.\n");
224                exit(-1);
225            }
226            strcpy(mebuf, pwdent->pw_name);
227        }
228        if (nethim) {
229                sp = getservbyname("write", "tcp");
230                if (sp == 0) {
231                        printf("tcp/write: unknown service\n");
232                        exit(1);
233                }
234                sin.sin_family = hp->h_addrtype;
235                bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
236                sin.sin_port = sp->s_port;
237                fds = socket(hp->h_addrtype, SOCK_STREAM, 0);
238                if (fds < 0) {
239                        perror("socket");
240                        exit(1);
241                }
242                if (connect(fds, (char *)&sin, sizeof (sin)) < 0) {
243                        perror("connect");
244                        close(fds);
245                        exit(1);
246                }
247
248                write(fds, me, strlen(me));
249                write(fds, "@", 1);
250                gethostname(myhost, sizeof (myhost));
251                write(fds, myhost, strlen(myhost));
252                write(fds, " ", 1);
253                write(fds, him, strlen(him));
254                if (histtya) {
255                        write(fds, " ", 1);
256                        write(fds, histtya, strlen(histtya));
257                }
258                write(fds, "\r\n", 2);
259                sigs(eof);
260                tf = fdopen(fds, "r+");
261                while (1) {
262                        if (fgets(buf, sizeof(buf), tf) == NULL) exit(1);
263                        if (buf[0] == '\n') break;
264                        write(1, buf, strlen(buf));
265                }
266        } else {
267            if (access(histty, 0) < 0) {
268                fprintf(stderr, "write: No such tty\n");
269                exit(1);
270            }
271            signal(SIGALRM, timout);
272            alarm(5);
273#if !defined(ultrix) && !defined(SOLARIS)
274            if (setpgrp(0,0))
275            if (setpgrp())
276                 perror("setpgrp 0");
277#endif
278            if (stat(histty, &stbuf) < 0 || (stbuf.st_mode&020) == 0
279                        || (tf = fopen(histty, "w")) == NULL) {
280                fprintf(stderr, "write: Permission denied\n");
281                exit(1);
282            }
283#ifndef SOLARIS
284            if (setpgrp(0,getpid()))
285                 perror("setpgrp !0");
286#endif
287            alarm(0);
288            sigs(eof);
289            if (netme) {
290                printf("\n");
291                fflush(stdout);
292                fprintf(tf,
293                 "\r\nMessage from %s on %s at %d:%02d ...\r\n\007\007\007",
294                 me, mytty, localclock->tm_hour, localclock->tm_min);
295            } else
296            { char hostname[32];
297              gethostname(hostname, sizeof (hostname));
298              fprintf(tf,
299                 "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007",
300                 me, hostname, mytty, localclock->tm_hour, localclock->tm_min);
301            }
302            fflush(tf);
303            fds = fileno(tf);
304
305        }
306        for (;;) {
307                char buf[BUFSIZ];
308                register char *bp;
309                i = read(0, buf, sizeof buf);
310                if (i <= 0)
311                        eof();
312                if ((!netme) && buf[0] == '!') {
313                        buf[i] = 0;
314                        ex(buf);
315                        continue;
316                }
317                for (bp = buf; --i >= 0; bp++) {
318                        if (*bp == '\n')
319                                putc('\r', tf);
320
321                        if (!isascii(*bp)) {
322                                putc('M', tf);
323                                putc('-', tf);
324                                *bp = toascii(*bp);
325                        }
326
327                        if (isprint(*bp) ||
328                            *bp == ' ' || *bp == '\t' || *bp == '\n'
329                            || *bp == '\r') {
330                                putc(*bp, tf);
331                        } else {
332                                putc('^', tf);
333                                putc(*bp ^ 0100, tf);
334                        }
335
336                        if (*bp == '\n')
337                                fflush(tf);
338
339                        if (ferror(tf) || feof(tf)) {
340                                printf("\n\007Write failed (%s logged out?)\n",
341                                        him);
342                                exit(1);
343                        }
344                }
345        }
346}
347
348timout()
349{
350
351        fprintf(stderr, "write: Timeout opening their tty\n");
352        exit(1);
353}
354
355eof()
356{
357
358        if (!nethim) {
359            fprintf(tf, "EOF\r\n");
360            fflush(tf);
361        }
362        exit(0);
363}
364
365ex(bp)
366        char *bp;
367{
368        register int i;
369
370        sigs(SIG_IGN);
371        i = fork();
372        if (i < 0) {
373                printf("Try again\n");
374                goto out;
375        }
376        if (i == 0) {
377                fclose(tf);             /* Close his terminal */
378                setgid(getgid());       /* Give up effective group privs */
379                sigs((int (*)())0);
380                execl(getenv("SHELL") ?
381                    getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
382                exit(0);
383        }
384        while (wait((int *)NULL) != i)
385                ;
386        printf("!\n");
387out:
388        sigs(eof);
389}
390
391sigs(sig)
392        int (*sig)();
393{
394        register int i;
395
396        for (i=0; signum[i]; i++)
397                signal(signum[i], sig);
398}
Note: See TracBrowser for help on using the repository browser.