chiark / gitweb /
debugging for thing that crashed
[innduct.git] / frontends / feedone.c
1 /*  $Id: feedone.c 6135 2003-01-19 01:15:40Z rra $
2 **
3 **  Connect to the NNTP server and feed one article.
4 */
5
6 #include "config.h"
7 #include "clibrary.h"
8 #include <errno.h>
9
10 #include "inn/messages.h"
11 #include "libinn.h"
12 #include "nntp.h"
13
14
15 static FILE     *FromServer;
16 static FILE     *ToServer;
17 static int      Tracing;
18
19
20 /*
21 **  Read a line from the server or die trying.
22 */
23 static void
24 GetFromServer(buff, size, text)
25     char        *buff;
26     int         size;
27     char        *text;
28 {
29     if (fgets(buff, size, FromServer) == NULL)
30         sysdie("s", text);
31     if (Tracing)
32         printf("S: %s", buff);
33 }
34
35
36 /*
37 **  Flush a stdio FILE; exit if there are any errors.
38 */
39 static void
40 SafeFlush(F)
41     FILE        *F;
42 {
43     if (fflush(F) == EOF || ferror(F))
44         sysdie("cannot send text to server");
45 }
46
47
48 static void
49 SendQuit(x)
50     int         x;
51 {
52     char        buff[BUFSIZ];
53
54     /* Close up. */
55     fprintf(ToServer, "quit\r\n");
56     SafeFlush(ToServer);
57     fclose(ToServer);
58     GetFromServer(buff, sizeof buff, "cannot get reply to quit");
59     exit(x);
60 }
61
62
63 static void
64 Usage()
65 {
66     fprintf(stderr, "Usage: feedone [-r|-m msgid] [-p] [-t] articlefile\n");
67     exit(1);
68 }
69
70
71 int
72 main(ac, av)
73     int         ac;
74     char        *av[];
75 {
76     static char MESGIDHDR[] = "Message-ID:";
77     int         i;
78     FILE        *F;
79     char        buff[BUFSIZ];
80     char        *mesgid = NULL;
81     size_t      length;
82     char        *p;
83     char        *q;
84     bool        PostMode;
85
86     /* Set defaults. */
87     mesgid[0] = '\0';
88     PostMode = false;
89     message_program_name = "feedone";
90
91     /* Parse JCL. */
92     while ((i = getopt(ac, av, "m:prt")) != EOF)
93         switch (i) {
94         default:
95             Usage();
96             /* NOTREACHED */
97         case 'm':                       /* Specified Message-ID */
98             if (*optarg == '<')
99                 mesgid = optarg;
100             else
101                 mesgid = concat("<", optarg, ">", (char *) 0);
102             break;
103         case 'p':                       /* Use Post, not ihave  */
104             PostMode = true;
105             break;
106         case 'r':                       /* Random Message-ID    */
107             length = snprintf(NULL, 0, "<%ld@%ld>", (long) getpid(),
108                               (long) time(NULL));
109             mesgid = xmalloc(length + 1);
110             snprintf(mesgid, length, "<%ld@%ld>", (long) getpid(),
111                      (long) time(NULL));
112             break;
113         case 't':
114             Tracing = true;
115             break;
116         }
117     ac -= optind;
118     av += optind;
119
120     /* One argument; the input filename. */
121     if (ac != 1)
122         Usage();
123     if ((F = fopen(av[0], "r")) == NULL)
124         sysdie("cannot open input");
125
126     /* Scan for the message-id. */
127     if (mesgid == NULL) {
128         while (fgets(buff, sizeof buff, F) != NULL)
129             if (strncasecmp(buff, MESGIDHDR, strlen(MESGIDHDR)) == 0) {
130                 if ((p = strchr(buff, '<')) == NULL
131                  || (q = strchr(p, '>')) == NULL)
132                     die("bad message ID line");
133                 q[1] = '\0';
134                 mesgid = xstrdup(p);
135                 break;
136             }
137         if (mesgid == NULL)
138             die("no message ID");
139     }
140
141     /* Connect to the server. */
142     if (NNTPremoteopen(NNTP_PORT, &FromServer, &ToServer, buff) < 0
143      || FromServer == NULL
144      || ToServer == NULL) {
145         if (buff[0])
146             warn("server says: %s", buff);
147         sysdie("cannot connect to server");
148     }
149
150     /* Does the server want this article? */
151     if (PostMode) {
152         fprintf(ToServer, "post\r\n");
153         i = NNTP_START_POST_VAL;
154     }
155     else {
156         fprintf(ToServer, "ihave %s\r\n", mesgid);
157         i = NNTP_SENDIT_VAL;
158     }
159     SafeFlush(ToServer);
160     GetFromServer(buff, sizeof buff, "cannot offer article to server");
161     if (atoi(buff) != i) {
162         warn("server doesn't want the article: %s", buff);
163         SendQuit(1);
164     }
165
166     /* Send the file over. */
167     fseeko(F, 0, SEEK_SET);
168     while (fgets(buff, sizeof buff, F) != NULL) {
169         if (strncasecmp(buff, MESGIDHDR, strlen(MESGIDHDR)) == 0) {
170             fprintf(ToServer, "%s %s\r\n", MESGIDHDR, mesgid);
171             continue;
172         }
173         if ((p = strchr(buff, '\n')) != NULL)
174             *p = '\0';
175         fprintf(ToServer, buff[0] == '.' ? ".%s\r\n" : "%s\r\n",
176                 buff);
177         SafeFlush(ToServer);
178     }
179     fprintf(ToServer, ".\r\n");
180     SafeFlush(ToServer);
181     fclose(F);
182
183     /* How did the server respond? */
184     GetFromServer(buff, sizeof buff,
185         "no reply from server after sending the article");
186     i = PostMode ? NNTP_POSTEDOK_VAL : NNTP_TOOKIT_VAL;
187     if (atoi(buff) != i)
188         sysdie("cannot send article to the server: %s", buff);
189
190     SendQuit(0);
191     /* NOTREACHED */
192 }