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