Fixed a little bug when the newsrc wasn't found.
[noose.git] / main.c
blob9fe768554e4a953f7de972a4e844a519a9f4f5f0
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);
144 ndat->newsrc = NULL;
146 if(newsrcs[i] == NULL) {
147 fprintf(stderr, "%s: Please specify a newsrc file to use.\n",
148 PROGNAME);
149 return -1;
151 return 0;
154 int do_check(noose_t *ndat, char *group)
156 int nsubbedgroups, i;
157 char **subbedgroups;
159 if(ndat->newsrc == NULL)
160 if(setnewsrc(ndat) != 0) return -1;
162 if(group == NULL) {
163 i = newsrc_getsubscribedgroups(ndat->newsrc, &nsubbedgroups,
164 &subbedgroups);
165 if(i != 0) {
166 if(ndat->verbose >= 0)
167 fprintf(stderr, "%s: Couldn't read subscribed groups from "
168 "your newsrc.\n", PROGNAME);
169 return -1;
171 for(i = 0; i < nsubbedgroups; i++) {
172 checksingle(ndat, subbedgroups[i]);
173 free(subbedgroups[i]);
175 } else {
176 checksingle(ndat, group);
179 return 0;
182 int checksingle(noose_t *ndat, char *group)
184 rangelist_t *rl, *p;
185 int i, narticles;
187 rl = rl_new(0, 0, NULL);
189 if(nntp_cmd_group(ndat->nh, group, NULL, &rl->begin, &rl->end) != 0) {
190 if(ndat->verbose >= 0)
191 fprintf(stderr, "%s: nntp_cmd_group failed.\n", PROGNAME);
192 return -1;
195 newsrc_filter(ndat->newsrc, group, &rl);
197 narticles = 0;
198 p = rl;
199 while(p != NULL) {
200 for(i = p->begin; i > 0 && i <= p->end; i++) {
201 if(nntp_cmd_article(ndat->nh, i, NULL, NULL) == 0) {
202 narticles++;
205 p = p->next;
208 if(narticles > 0 || ndat->verbose > 0) {
209 printf("There %s %d unread article%s in newsgroup %s.\n",
210 (narticles == 1)?"is":"are", narticles,
211 (narticles == 1)?"":"s", group);
214 rl_delete(rl);
215 return 0;
218 int do_read(noose_t *ndat, char *group, int article)
220 char *artbody, *arthead;
222 if(nntp_cmd_group(ndat->nh, group, NULL, NULL, NULL) == -1) {
223 if(ndat->verbose >= 0)
224 fprintf(stderr, "%s: nntp_cmd_group failed.\n", PROGNAME);
225 return -1;
228 if(nntp_cmd_article(ndat->nh, article, &arthead, &artbody) == -1) {
229 if(ndat->verbose >= 0)
230 fprintf(stderr, "%s: nntp_cmd_article failed.\n", PROGNAME);
231 return -1;
234 printf("%s%s", arthead, artbody);
235 free(arthead);
236 free(artbody);
237 return 0;
240 void usage(char *msg)
242 printf("%s: %s\n\n", PROGNAME, msg);
243 printf("usage: %s [options...] <command>\n\n"
244 "Valid options are:\n"
245 " -q Quiet mode. This makes `check' only report groups\n"
246 " with more than zero new messages in them.\n"
247 " -v Verbose. The inverse of quiet.\n"
248 " -n server Specify NNTP server.\n"
249 " -r rcfile Specify newsrc file.\n"
250 "\n"
251 "Valid commands are:\n"
252 " check [g] Return how many unread posts are in all subscribed\n"
253 " groups, or just group g if specified.\n"
254 " read <g> <n> Grab the entirity of article n from group g.\n",
255 PROGNAME);
256 exit(EXIT_FAILURE);
259 /* EOF main.c */