|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)inews.c 1.12 (Berkeley) 7/13/87";
3: #endif
4:
5: /*
6: * Itty-bitty inews for talking to remote server.
7: * Simply accept input on stdin (or via a named file) and dump this
8: * to the server; add a From: and Path: line if missing in the original.
9: * Print meaningful errors from the server.
10: * Limit .signature files to MAX_SIGNATURE lines.
11: *
12: * Original by Steven Grady <[email protected]>, with thanks from
13: * Phil Lapsley <[email protected]>, who is now responsible for it.
14: */
15:
16: #include <stdio.h>
17: #include <pwd.h>
18: #include <ctype.h>
19: #include <strings.h>
20: #include "../common/conf.h"
21: #include "../common/response_codes.h"
22:
23: #define MAX_SIGNATURE 4
24:
25: extern FILE *ser_wr_fp;
26:
27: char host_name[256];
28:
29: main(argc, argv)
30: int argc;
31: char *argv[];
32: {
33: char line[256], s[256];
34: int seen_fromline, in_header;
35: int response;
36: char *server;
37: char *getserverbyfile();
38: register char *cp;
39:
40: ++argv;
41: while (argc > 1)
42: if (*argv[0] == '-') {
43: ++argv;
44: --argc;
45: } else
46: break;
47:
48: if (argc > 1) {
49: if (freopen(*argv, "r", stdin) == NULL) {
50: perror(*argv);
51: exit(1);
52: }
53: }
54:
55: uname(host_name);
56:
57: server = getserverbyfile(SERVER_FILE);
58: if (server == NULL) {
59: fprintf(stderr,
60: "Can't get the name of the news server from %s.\n",
61: SERVER_FILE);
62: fprintf(stderr,
63: "Either fix this file, or put NNTPSERVER in your enviroment.\n");
64: exit(1);
65: }
66:
67: response = server_init(server);
68: if (response < 0) {
69: printf("Couldn't connect to %s news server, try again later.\n",
70: server);
71: exit(1);
72: }
73:
74: if (handle_server_response(response, server) < 0
75: || response == OK_NOPOST) {
76: close_server();
77: exit(1);
78: }
79:
80: put_server("POST");
81: (void) get_server(line, sizeof(line));
82: if (*line != CHAR_CONT) {
83: if (atoi(line) == ERR_NOPOST) {
84: close_server();
85: fprintf(stderr,
86: "Sorry, you can't post from this machine.\n");
87: exit(1);
88: } else {
89: close_server();
90: fprintf(stderr, "Remote error: %s\n", line);
91: exit(1);
92: }
93: }
94:
95: in_header = 1;
96: seen_fromline = 0;
97:
98: while (gets(s) != NULL) {
99: if (s[0] == '.') /* Single . is eof, so put in extra one */
100: (void) fputc('.', ser_wr_fp);
101: if (in_header && strneql(s, "From:", sizeof("From:")-1))
102: seen_fromline = 1;
103: if (in_header && s[0] == '\0') {
104: in_header = 0;
105: if (!seen_fromline)
106: gen_frompath();
107: }
108: fprintf(ser_wr_fp, "%s\r\n", s);
109: }
110:
111: append_signature();
112:
113: fprintf(ser_wr_fp, ".\r\n");
114: (void) fflush(ser_wr_fp);
115: (void) get_server(line, sizeof(line));
116: if (*line != CHAR_OK) {
117: if (atoi(line) == ERR_POSTFAIL) {
118: close_server();
119: printf("Article not accepted by server; not posted.\n");
120: for (cp = line + 4; *cp && *cp != '\r'; cp++)
121: if (*cp == '\\')
122: putchar('\n');
123: else
124: putchar(*cp);
125: exit(1);
126: } else {
127: close_server();
128: fprintf(stderr, "Remote error: %s\n", line);
129: exit(1);
130: }
131: }
132:
133: /*
134: * Close server sends the server a
135: * "quit" command for us, which is why we don't send it.
136: */
137:
138: close_server();
139:
140: exit(0);
141: }
142:
143: /*
144: * append_signature -- append the person's .signature file if
145: * they have one. Limit .signature to MAX_SIGNATURE lines.
146: */
147:
148: append_signature()
149: {
150: char line[256], sigfile[256];
151: char *cp;
152: struct passwd *passwd;
153: FILE *fp;
154: char *index();
155: int count = 0;
156:
157: passwd = getpwuid(getuid());
158: if (passwd == NULL)
159: return;
160:
161: (void) strcpy(sigfile, passwd->pw_dir);
162: (void) strcat(sigfile, "/");
163: (void) strcat(sigfile, ".signature");
164:
165: fp = fopen(sigfile, "r");
166: if (fp == NULL)
167: return;
168:
169: while (fgets(line, sizeof (line), fp)) {
170: count++;
171: if (count > MAX_SIGNATURE) {
172: fprintf(stderr,
173: "Warning: .signature files should be no longer than %d lines.\n",
174: MAX_SIGNATURE);
175: fprintf(stderr,
176: "(Only %d lines of your .signature were posted.)\n",
177: MAX_SIGNATURE);
178: break;
179: }
180: if (cp = index(line, '\n'))
181: *cp = '\0';
182: fprintf(ser_wr_fp, "%s\r\n", line);
183: }
184: (void) fclose(fp);
185: }
186:
187:
188: /*
189: * gen_frompath -- generate From: and Path: lines, in the form
190: *
191: * From: [email protected] (full_name)
192: * Path: host!user
193: *
194: * This routine should only be called if the message doesn't have
195: * a From: line in it.
196: */
197:
198: gen_frompath()
199: {
200: char *full_name;
201: char *cp;
202: struct passwd *passwd;
203: char *index(), *getenv();
204:
205: passwd = getpwuid(getuid());
206:
207: full_name = getenv("NAME");
208: if (full_name == NULL) {
209: full_name = passwd->pw_gecos;
210: if ((cp = index(full_name, ',')))
211: *cp = '\0';
212: }
213:
214: #ifdef DOMAIN
215:
216: /* A heuristic to see if we should tack on a domain */
217:
218: cp = index(host_name, '.');
219: if (cp)
220: fprintf(ser_wr_fp, "From: %s@%s (",
221: passwd->pw_name,
222: host_name);
223: else
224: fprintf(ser_wr_fp, "From: %s@%s.%s (",
225: passwd->pw_name,
226: host_name,
227: DOMAIN);
228: #else
229: fprintf(ser_wr_fp, "From: %s@%s (",
230: passwd->pw_name,
231: host_name);
232: #endif
233:
234: for (cp = full_name; *cp != '\0'; ++cp)
235: if (*cp != '&')
236: putc(*cp, ser_wr_fp);
237: else { /* Stupid & hack. God damn it. */
238: putc(toupper(passwd->pw_name[0]), ser_wr_fp);
239: fprintf(ser_wr_fp, passwd->pw_name+1);
240: }
241:
242: fprintf(ser_wr_fp, ")\r\n");
243:
244: fprintf(ser_wr_fp, "Path: %s!%s\r\n", host_name, passwd->pw_name);
245: }
246:
247:
248: /*
249: * strneql -- determine if two strings are equal in the first n
250: * characters, ignoring case.
251: *
252: * Parameters: "a" and "b" are the pointers
253: * to characters to be compared.
254: * "n" is the number of characters to compare.
255: *
256: * Returns: 1 if the strings are equal, 0 otherwise.
257: *
258: * Side effects: None.
259: */
260:
261: strneql(a, b, n)
262: register char *a, *b;
263: int n;
264: {
265: char lower();
266:
267: while (n && lower(*a) == lower(*b)) {
268: if (*a == '\0')
269: return (1);
270: a++;
271: b++;
272: n--;
273: }
274: if (n)
275: return (0);
276: else
277: return (1);
278: }
279:
280: /*
281: * lower -- convert a character to lower case, if it's
282: * upper case.
283: *
284: * Parameters: "c" is the character to be
285: * converted.
286: *
287: * Returns: "c" if the character is not
288: * upper case, otherwise the lower
289: * case eqivalent of "c".
290: *
291: * Side effects: None.
292: */
293:
294: char lower(c)
295: register char c;
296: {
297: if (isascii(c) && isupper(c))
298: c = c - 'A' + 'a';
299: return(c);
300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.