Commit | Line | Data |
---|---|---|
2117e02e MW |
1 | #include <sys/types.h> |
2 | #include <sys/stat.h> | |
3 | #include <utmp.h> | |
4 | #ifndef UTMP_FILE | |
5 | #ifdef _PATH_UTMP | |
6 | #define UTMP_FILE _PATH_UTMP | |
7 | #else | |
8 | #define UTMP_FILE "/etc/utmp" | |
9 | #endif | |
10 | #endif | |
11 | #include "readwrite.h" | |
12 | #include "stralloc.h" | |
13 | #include "substdio.h" | |
14 | #include "subfd.h" | |
15 | #include "open.h" | |
16 | #include "byte.h" | |
17 | #include "str.h" | |
18 | #include "headerbody.h" | |
19 | #include "hfield.h" | |
20 | #include "env.h" | |
21 | #include "exit.h" | |
22 | ||
23 | substdio ssutmp; | |
24 | char bufutmp[sizeof(struct utmp) * 16]; | |
25 | int fdutmp; | |
26 | substdio sstty; | |
27 | char buftty[1024]; | |
28 | int fdtty; | |
29 | ||
30 | struct utmp ut; | |
31 | char line[sizeof(ut.ut_line) + 1]; | |
32 | stralloc woof = {0}; | |
33 | stralloc tofrom = {0}; | |
34 | stralloc text = {0}; | |
35 | ||
36 | void doit(s,n) char *s; int n; | |
37 | { | |
38 | if (!stralloc_catb(&text,s,n)) _exit(0); | |
39 | if (text.len > 78) text.len = 78; | |
40 | } | |
41 | void dobody(h) stralloc *h; { doit(h->s,h->len); } | |
42 | void doheader(h) stralloc *h; | |
43 | { | |
44 | int i; | |
45 | if (hfield_known(h->s,h->len) == H_SUBJECT) | |
46 | { | |
47 | i = hfield_skipname(h->s,h->len); | |
48 | doit(h->s + i,h->len - i); | |
49 | } | |
50 | } | |
51 | void finishheader() { ; } | |
52 | ||
53 | void main() | |
54 | { | |
55 | char *user; | |
56 | char *sender; | |
57 | char *userext; | |
58 | struct stat st; | |
59 | int i; | |
60 | ||
61 | if (chdir("/dev") == -1) _exit(0); | |
62 | ||
63 | if (!(user = env_get("USER"))) _exit(0); | |
64 | if (!(sender = env_get("SENDER"))) _exit(0); | |
65 | if (!(userext = env_get("LOCAL"))) _exit(0); | |
66 | if (str_len(user) > sizeof(ut.ut_name)) _exit(0); | |
67 | ||
68 | if (!stralloc_copys(&tofrom,"*** TO <")) _exit(0); | |
69 | if (!stralloc_cats(&tofrom,userext)) _exit(0); | |
70 | if (!stralloc_cats(&tofrom,"> FROM <")) _exit(0); | |
71 | if (!stralloc_cats(&tofrom,sender)) _exit(0); | |
72 | if (!stralloc_cats(&tofrom,">")) _exit(0); | |
73 | ||
74 | for (i = 0;i < tofrom.len;++i) | |
75 | if ((tofrom.s[i] < 32) || (tofrom.s[i] > 126)) | |
76 | tofrom.s[i] = '_'; | |
77 | ||
78 | if (!stralloc_copys(&text," ")) _exit(0); | |
79 | if (headerbody(subfdin,doheader,finishheader,dobody) == -1) _exit(0); | |
80 | ||
81 | for (i = 0;i < text.len;++i) | |
82 | if ((text.s[i] < 32) || (text.s[i] > 126)) | |
83 | text.s[i] = '/'; | |
84 | ||
85 | if (!stralloc_copys(&woof,"\015\n\007")) _exit(0); | |
86 | if (!stralloc_cat(&woof,&tofrom)) _exit(0); | |
87 | if (!stralloc_cats(&woof,"\015\n")) _exit(0); | |
88 | if (!stralloc_cat(&woof,&text)) _exit(0); | |
89 | if (!stralloc_cats(&woof,"\015\n")) _exit(0); | |
90 | ||
91 | fdutmp = open_read(UTMP_FILE); | |
92 | if (fdutmp == -1) _exit(0); | |
93 | substdio_fdbuf(&ssutmp,read,fdutmp,bufutmp,sizeof(bufutmp)); | |
94 | ||
95 | while (substdio_get(&ssutmp,&ut,sizeof(ut)) == sizeof(ut)) | |
96 | if (!str_diffn(ut.ut_name,user,sizeof(ut.ut_name))) | |
97 | { | |
98 | byte_copy(line,sizeof(ut.ut_line),ut.ut_line); | |
99 | line[sizeof(ut.ut_line)] = 0; | |
100 | if (line[0] == '/') continue; | |
101 | if (!line[0]) continue; | |
102 | if (line[str_chr(line,'.')]) continue; | |
103 | fdtty = open_append(line); | |
104 | if (fdtty == -1) continue; | |
105 | if (fstat(fdtty,&st) == -1) { close(fdtty); continue; } | |
106 | if (!(st.st_mode & 0100)) { close(fdtty); continue; } | |
107 | if (st.st_uid != getuid()) { close(fdtty); continue; } | |
108 | substdio_fdbuf(&sstty,write,fdtty,buftty,sizeof(buftty)); | |
109 | substdio_putflush(&sstty,woof.s,woof.len); | |
110 | close(fdtty); | |
111 | } | |
112 | _exit(0); | |
113 | } |