BSD 2 development
[unix-history] / src / msgs.c
CommitLineData
b09f1d89
BJ
1/* Copyright (c) 1979 Regents of the University of California */
2/* #define CORY */
3#include <stdio.h>
4#include <sys/types.h>
5#include <signal.h>
6#include <sys/dir.h>
7#include <sys/stat.h>
8#include <ctype.h>
9
10typedef char bool;
11
12FILE *f;
13bool hdrs;
14bool qopt;
15char *sep;
16bool ruptible;
17int onintr();
18
19main(argc, argv)
20 int argc;
21 char *argv[];
22{
23 char obuf[BUFSIZ];
24 bool newrc, already, argfirst = 0;
25 int rcfirst, lastmsg, firstmsg;
26 FILE *bounds, *msgsrc;
27 int i, nextty;
28 bool hush = 0;
29 bool send = 0;
30
31 ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
32 if (ruptible)
33 signal(SIGINT, SIG_DFL);
34 setbuf(stdout, obuf);
35 argc--, argv++;
36 while (argc >= 1) {
37 if (isdigit(argv[0][0])) {
38 argfirst = 1;
39 rcfirst = atoi(argv[0]);
40 } else switch (argv[0][1]) {
41
42 case 'f':
43 hush++;
44 break;
45
46 case 'q':
47 qopt++;
48 break;
49
50 case 'h':
51 hdrs++;
52 break;
53
54 case 's':
55 send++;
56 break;
57
58 default:
59 fprintf(stderr, "usage: msgs [ -f ] [ number ]\n");
60 exit(1);
61 }
62 argc--, argv++;
63 }
64 if (!send) {
65 setuid(getuid());
66 if (chdir(getenv("HOME")) < 0)
67 perror(getenv("HOME")), exit(1);
68 newrc = 0;
69 msgsrc = fopen(".msgsrc", "r");
70 nextty = 1;
71 if (msgsrc != NULL) {
72 fscanf(msgsrc, "%d\n", &i);
73 fclose(msgsrc);
74 nextty = i;
75 if (!argfirst)
76 rcfirst = i;
77 } else
78 newrc = 1;
79 msgsrc = fopen(".msgsrc", "w");
80 if (msgsrc == NULL)
81 perror(".msgsrc"), exit(1);
82 }
83 if (chdir("/usr/msgs") < 0)
84 perror("/usr/msgs"), exit(1);
85 bounds = fopen("bounds", "r");
86 if (bounds == NULL) {
87 FILE *d = fopen(".", "r");
88 struct direct dirent;
89
90 if (d == NULL)
91 perror("/usr/msgs"), exit(1);
92 firstmsg = 25000;
93 lastmsg = 0;
94 while (fread(&dirent, sizeof dirent, 1, d) == 1) {
95 register char *cp = dirent.d_name;
96 register int i = 0;
97
98 if (dirent.d_ino == 0)
99 continue;
100 while (isdigit(*cp))
101 i = i * 10 + *cp++ - '0';
102 if (*cp)
103 continue;
104 if (i > lastmsg)
105 lastmsg = i;
106 if (i < firstmsg)
107 firstmsg = i;
108 }
109 if (firstmsg == 25000) {
110 firstmsg = 1;
111 lastmsg = 0;
112 }
113 fclose(d);
114 if (send) {
115 unlink("bounds");
116 bounds = fopen("bounds", "w");
117#ifdef CORY
118 chmod("bounds", 0644);
119#else
120 chmod("bounds", 0666);
121#endif
122 if (bounds == NULL)
123 perror("bounds"), exit(1);
124 fprintf(bounds, "%d %d\n", firstmsg, lastmsg);
125 fclose(bounds);
126 }
127 } else {
128 fscanf(bounds, "%d %d\n", &firstmsg, &lastmsg);
129 fclose(bounds);
130 }
131 if (send) {
132 char newname[16];
133 FILE *newm;
134
135 sprintf(newname, "%d", lastmsg+1);
136 bounds = fopen("bounds", "w");
137 if (bounds == NULL)
138 perror("bounds"), exit(1);
139 fprintf(bounds, "%d %d\n", firstmsg, lastmsg+1);
140 fclose(bounds);
141 newm = fopen(newname, "w");
142 if (newm == NULL)
143 fprintf(stderr, "/usr/msgs/"), perror(newname), exit(1);
144 chmod(newname, 0644);
145 for (;;) {
146 register c;
147 c = getchar();
148 if (feof(stdin))
149 exit(0);
150 if (ferror(stdin))
151 exit(1);
152 putc(c, newm);
153 }
154 }
155 if (!newrc)
156 firstmsg = rcfirst;
157 already = 0;
158 for (i = firstmsg; i <= lastmsg; i++) {
159 register int c;
160 char inline[BUFSIZ];
161 struct stat stbuf;
162 char fname[16];
163
164 sprintf(fname, "%d", i);
165 f = fopen(fname, "r");
166 if (f == NULL)
167 continue;
168 if (qopt) {
169 fseek(msgsrc, (long) 0, 0);
170 fprintf(msgsrc, "%d\n", nextty);
171 fflush(msgsrc);
172 printf("There are new messages.\n");
173 exit(0);
174 }
175 if (already)
176 printf("\n");
177 already = 1;
178 fseek(msgsrc, (long) 0, 0);
179 fprintf(msgsrc, "%d\n", nextty);
180 fflush(msgsrc);
181 printf("Message %d:\n", i);
182 fgets(inline, sizeof inline, f);
183 printf("%s", inline);
184 if (fgets(inline, sizeof inline, f)) {
185 if (strcmp(inline, "To: msgs\n") != 0 && inline[0] != '\n')
186 printf("%s", inline);
187 if (fgets(inline, sizeof inline, f) && inline[0] != '\n')
188 printf("%s", inline);
189 }
190 c = getc(f);
191 sep = "-";
192 if (c == '\n')
193 c = getc(f);
194 if (!feof(f))
195 printf("(%d more lines)", linecnt(f));
196 if (hdrs) {
197 printf("\n-----\n");
198 fclose(f);
199 continue;
200 }
201 if (feof(f))
202 printf("(continue) [yq] ");
203 else
204 printf(" type [ynq] ? ");
205 fflush(stdout);
206 inline[0] = 0;
207 fgets(inline, sizeof inline, stdin);
208 if (inline[0] == 0)
209 printf("\n");
210 if (inline[0] == 'q')
211 exit(1);
212 if (isdigit(inline[0])) {
213 sscanf(inline, "%d", &i);
214 printf("--Goto %d--\n", i);
215 i--;
216 fflush(stdout);
217 fclose(f);
218 continue;
219 }
220 if (inline[0] == 'n' || inline[0] == 'N') {
221 printf("--Flushed--\n");
222 fflush(stdout);
223 fclose(f);
224 if (i >= nextty)
225 nextty = i + 1;
226 continue;
227 }
228 if (ruptible)
229 signal(SIGINT, onintr);
230 if (!feof(f))
231 for (;;) {
232 putchar(c);
233 c = getc(f);
234 if (feof(f))
235 break;
236 }
237 printf("--%s--\n", sep);
238 if (i >= nextty)
239 nextty = i + 1;
240 fflush(stdout);
241 if (ruptible)
242 signal(SIGINT, SIG_DFL);
243 fclose(f);
244 }
245 fseek(msgsrc, (long) 0, 0);
246 fprintf(msgsrc, "%d\n", nextty);
247 fclose(msgsrc);
248 if (qopt)
249 exit(0);
250 if (!already && !hush)
251 printf("No messages.\n");
252 exit(0);
253}
254
255onintr()
256{
257
258 sep = "Skip";
259 printf("\n");
260 fseek(f, (long) 0, 2);
261}
262
263linecnt(f)
264 FILE *f;
265{
266 off_t ftell();
267 off_t oldpos = ftell(f);
268 int l = 0;
269 char lbuf[BUFSIZ];
270
271 while (fgets(lbuf, sizeof lbuf, f))
272 l++;
273 clearerr(f);
274 fseek(f, oldpos, 0);
275 return (l);
276}