chiark / gitweb /
merge
[inn-innduct.git] / frontends / getlist.c
1 /*  $Id: getlist.c 6135 2003-01-19 01:15:40Z rra $
2 **
3 **  Get a file list from an NNTP server.
4 */
5 #include "config.h"
6 #include "clibrary.h"
7 #include <errno.h>
8 #include <syslog.h>
9
10 #include "inn/innconf.h"
11 #include "inn/messages.h"
12 #include "inn/qio.h"
13 #include "libinn.h"
14 #include "paths.h"
15
16
17 /*
18 **  Print usage message and exit.
19 */
20 static void
21 Usage(void)
22 {
23     fprintf(stderr, "Usage: getlist [-p port] [-h host] [-A] [type [pat [groups]]\n");
24     exit(1);
25 }
26
27
28 int
29 main(int ac, char *av[])
30 {
31     FILE        *active;
32     FILE        *FromServer;
33     FILE        *ToServer;
34     QIOSTATE    *qp;
35     char        *field4;
36     char        *types;
37     char        *host;
38     char        *line;
39     const char  *list;
40     char        *p;
41     char        *pattern;
42     char        buff[512 + 1];
43     int         port;
44     int         authinfo;
45     int         i;
46
47     /* First thing, set up our identity. */
48     message_program_name = "getlist";
49
50     if (!innconf_read(NULL))
51         exit(1);
52
53     /* Set defaults. */
54     host = NULL;
55     pattern = NULL;
56     types = NULL;
57     port = NNTP_PORT;
58     authinfo = 0;
59
60     /* Parse JCL. */
61     while ((i = getopt(ac, av, "Ah:p:")) != EOF)
62         switch (i) {
63         default:
64             Usage();
65             /* NOTREACHED */
66         case 'A':
67             authinfo = 1;
68             break;
69         case 'h':
70             host = optarg;
71             break;
72         case 'p':
73             port = atoi(optarg);
74             if (port <= 0)
75                 die("illegal value for -p option");
76             break;
77         }
78     ac -= optind;
79     av += optind;
80
81     /* Parse parameters. */
82     switch (ac) {
83     default:
84         Usage();
85         /* NOTREACHED */
86     case 0:
87     case 1:
88         break;
89     case 2:
90         pattern = av[1];
91         break;
92     case 3:
93         pattern = av[1];
94         types = av[2];
95         break;
96     }
97     if (av[0] == NULL)
98         list = "active";
99     else {
100         list = av[0];
101         if (strcmp(list, "active") != 0 && types != NULL)
102             Usage();
103         if (strcmp(list, "active") != 0 && strcmp(list, "newsgroups") != 0
104          && pattern != NULL)
105             Usage();
106     }
107
108     /* Open a connection to the server. */
109     if (host == NULL && (host = innconf->server) == NULL)
110         sysdie("cannot get server name");
111     buff[0] = '\0';
112     if (NNTPconnect(host, port, &FromServer, &ToServer, buff) < 0)
113         die("cannot connect to server: %s", buff[0] ? buff : strerror(errno));
114     if (authinfo && NNTPsendpassword(host, FromServer, ToServer) < 0)
115         die("cannot authenticate to server");
116
117     /* Get the data from the server. */
118     active = CAlistopen(FromServer, ToServer,
119                         (strcmp(list, "active") == 0) ? NULL : list);
120     if (active == NULL)
121         sysdie("cannot retrieve data");
122
123     /* Set up to read it quickly. */
124     if ((qp = QIOfdopen((int)fileno(active))) == NULL)
125         sysdie("cannot read temporary file");
126
127     /* Scan server's output, displaying appropriate lines. */
128     i = 1;
129     while ((line = QIOread(qp)) != NULL) {
130         i++;
131
132         /* No pattern means print all. */
133         if (pattern == NULL) {
134             printf("%s\n", line);
135             continue;
136         }
137
138         /* Get the group name, see if it's one we want. */
139         if ((p = strchr(line, ' ')) == NULL) {
140             warn("line %d is malformed", i);
141             continue;
142         }
143         *p = '\0';
144         if (!uwildmat(line, pattern))
145             continue;
146         *p = ' ';
147
148         /* If no group types, we want them all. */
149         if (types == NULL) {
150             printf("%s\n", line);
151             continue;
152         }
153
154         /* Find the fourth field. */
155         if ((p = strchr(p + 1, ' ')) == NULL) {
156             warn("line %d (field 2) is malformed", i);
157             continue;
158         }
159         if ((p = strchr(p + 1, ' ')) == NULL) {
160             warn("line %d (field 3) is malformed", i);
161             continue;
162         }
163         field4 = p + 1;
164         if ((p = strchr(field4, ' ')) != NULL) {
165             warn("line %d has more than 4 fields", i);
166             continue;
167         }
168
169         /* Is this the type of line we want? */
170         if (strchr(types, field4[0]) != NULL)
171             printf("%s\n", line);
172     }
173
174     /* Determine why we stopped */
175     if (QIOerror(qp)) {
176         syswarn("cannot read temporary file at line %d", i);
177         i = 1;
178     }
179     else if (QIOtoolong(qp)) {
180         warn("line %d is too long", i);
181         i = i;
182     }
183     else
184         i = 0;
185
186     /* All done. */
187     CAclose();
188     fprintf(ToServer, "quit\r\n");
189     fclose(ToServer);
190     fgets(buff, sizeof buff, FromServer);
191     fclose(FromServer);
192     exit(i);
193     /* NOTREACHED */
194 }