Import from CVS into darcs.
[noose.git] / main.c
blobea2ad632723f28aa4969805a7594a340a7bad464
1 /*
2 * main.c
3 * Created: Sun Feb 25 20:11:31 2001 by tek@wiw.org
4 * Revised: Sun Apr 22 19:09:44 2001 by tek@wiw.org
5 * Copyright 2001 Julian E. C. Squires (tek@wiw.org)
6 * This program comes with ABSOLUTELY NO WARRANTY.
7 * $Id: main.c,v 1.5 2001/04/22 21:41:23 tek Exp $
8 *
9 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
15 #include "noose.h"
17 typedef struct noose_s {
18 int verbose;
19 void *nh;
20 char *newsrc;
21 } noose_t;
23 void usage(char *msg);
24 int do_check(noose_t *ndat, char *group);
25 int checksingle(noose_t *ndat, char *group);
26 int do_read(noose_t *ndat, char *group, int article);
27 int setnewsrc(noose_t *ndat);
29 int main(int argc, char **argv)
31 enum { nocommand, check, read } command = nocommand;
32 char *group, *server;
33 noose_t ndat;
34 int i, j, article, ret;
36 ndat.verbose = 1;
37 ndat.newsrc = NULL;
38 server = getenv("NNTPSERVER");
40 for(i = 1; i < argc; i++) {
41 if(strcmp(argv[i], "-n") == 0) {
42 i++;
43 if(i == argc)
44 usage("Option `n' requires an argument.");
45 server = argv[i];
47 } else if(strcmp(argv[i], "-r") == 0) {
48 i++;
49 if(i == argc)
50 usage("Option `r' requires an argument.");
51 ndat.newsrc = malloc(strlen(argv[i])+1);
52 strcpy(ndat.newsrc, argv[i]);
54 } else if(argv[i][0] == '-') {
55 for(j = 1; j < strlen(argv[i]); j++)
56 switch(argv[i][j]) {
57 case 'q':
58 ndat.verbose--;
59 break;
61 case 'v':
62 ndat.verbose++;
63 break;
65 default:
66 usage("Bad option.");
68 } else if(strcmp(argv[i], "check") == 0) {
69 command = check;
70 i++;
71 if(i < argc) {
72 group = argv[i];
73 } else
74 group = NULL;
76 } else if(strcmp(argv[i], "read") == 0) {
77 command = read;
78 i++;
79 if(i+1 >= argc) usage("Too few arguments for `read'.");
80 group = argv[i];
81 i++;
82 article = atoi(argv[i]);
83 if(article == 0) usage("Invalid article number.");
85 } else
86 usage("Bad argument.");
88 if(command == nocommand) {
89 usage("No command specified.");
92 if(server == NULL)
93 server = DEFNNTPSERVER;
95 ndat.nh = nntp_connect(server);
96 if(ndat.nh == NULL) {
97 if(ndat.verbose >= 0)
98 fprintf(stderr, "%s: Failed to connect to `%s'.\n", PROGNAME,
99 server);
100 exit(EXIT_FAILURE);
103 switch(command) {
104 case check:
105 ret = do_check(&ndat, group);
106 break;
108 case read:
109 ret = do_read(&ndat, group, article);
110 break;
112 default:
113 fprintf(stderr, "Command unsupported.\n");
114 exit(EXIT_FAILURE);
117 if(ndat.newsrc) free(ndat.newsrc);
118 nntp_disconnect(ndat.nh);
119 exit((ret == 0)?EXIT_SUCCESS:EXIT_FAILURE);
122 int setnewsrc(noose_t *ndat)
124 char *home;
125 char *newsrcs[] = { "/.jnewsrc", "/.newsrc", NULL };
126 int i;
127 FILE *fp;
129 home = getenv("HOME");
130 if(home == NULL) {
131 fprintf(stderr, "%s: Please set HOME in your environment.\n",
132 PROGNAME);
133 return -1;
135 for(i = 0; newsrcs[i] != NULL; i++) {
136 ndat->newsrc = malloc(strlen(home)+strlen(newsrcs[i]));
137 strcpy(ndat->newsrc, home);
138 strcat(ndat->newsrc, newsrcs[i]);
139 if((fp = fopen(ndat->newsrc, "r")) != NULL) {
140 fclose(fp);
141 break;
143 free(ndat->newsrc);
145 if(newsrcs[i] == NULL) {
146 fprintf(stderr, "%s: Please specify a newsrc file to use.\n",
147 PROGNAME);
148 return -1;
150 return 0;
153 int do_check(noose_t *ndat, char *group)
155 int nsubbedgroups, i;
156 char **subbedgroups;
158 if(ndat->newsrc == NULL)
159 if(setnewsrc(ndat) != 0) return -1;
161 if(group == NULL) {
162 i = newsrc_getsubscribedgroups(ndat->newsrc, &nsubbedgroups,
163 &subbedgroups);
164 if(i != 0) {
165 if(ndat->verbose >= 0)
166 fprintf(stderr, "%s: Couldn't read subscribed groups from "
167 "your newsrc.\n", PROGNAME);
168 return -1;
170 for(i = 0; i < nsubbedgroups; i++) {
171 checksingle(ndat, subbedgroups[i]);
172 free(subbedgroups[i]);
174 } else {
175 checksingle(ndat, group);
178 return 0;
181 int checksingle(noose_t *ndat, char *group)
183 rangelist_t *rl, *p;
184 int i, narticles;
186 rl = rl_new(0, 0, NULL);
188 if(nntp_cmd_group(ndat->nh, group, NULL, &rl->begin, &rl->end) != 0) {
189 if(ndat->verbose >= 0)
190 fprintf(stderr, "%s: nntp_cmd_group failed.\n", PROGNAME);
191 return -1;
194 newsrc_filter(ndat->newsrc, group, &rl);
196 narticles = 0;
197 p = rl;
198 while(p != NULL) {
199 for(i = p->begin; i > 0 && i <= p->end; i++) {
200 if(nntp_cmd_article(ndat->nh, i, NULL, NULL) == 0) {
201 narticles++;
204 p = p->next;
207 if(narticles > 0 || ndat->verbose > 0) {
208 printf("There %s %d unread article%s in newsgroup %s.\n",
209 (narticles == 1)?"is":"are", narticles,
210 (narticles == 1)?"":"s", group);
213 rl_delete(rl);
214 return 0;
217 int do_read(noose_t *ndat, char *group, int article)
219 char *artbody, *arthead;
221 if(nntp_cmd_group(ndat->nh, group, NULL, NULL, NULL) == -1) {
222 if(ndat->verbose >= 0)
223 fprintf(stderr, "%s: nntp_cmd_group failed.\n", PROGNAME);
224 return -1;
227 if(nntp_cmd_article(ndat->nh, article, &arthead, &artbody) == -1) {
228 if(ndat->verbose >= 0)
229 fprintf(stderr, "%s: nntp_cmd_article failed.\n", PROGNAME);
230 return -1;
233 printf("%s%s", arthead, artbody);
234 free(arthead);
235 free(artbody);
236 return 0;
239 void usage(char *msg)
241 printf("%s: %s\n\n", PROGNAME, msg);
242 printf("usage: %s [options...] <command>\n\n"
243 "Valid options are:\n"
244 " -q Quiet mode. This makes `check' only report groups\n"
245 " with more than zero new messages in them.\n"
246 " -v Verbose. The inverse of quiet.\n"
247 " -n server Specify NNTP server.\n"
248 " -r rcfile Specify newsrc file.\n"
249 "\n"
250 "Valid commands are:\n"
251 " check [g] Return how many unread posts are in all subscribed\n"
252 " groups, or just group g if specified.\n"
253 " read <g> <n> Grab the entirity of article n from group g.\n",
254 PROGNAME);
255 exit(EXIT_FAILURE);
258 /* EOF main.c */