more sprintf removals
[citadel.git] / citadel / netsetup.c
1 /*
2  * $Id$
3  *
4  * Command-line utility to manipulate network configuration files
5  * Copyright (c) 1998  Art Cancro
6  *
7  */
8
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include "citadel.h"
15
16 struct roomshare {
17         struct roomshare *next;
18         char rs_name[30];
19         long rs_lastsent;
20         };
21
22 struct netnode {
23         char nn_nodename[32];
24         char nn_spoolcmd[SIZ];
25         struct roomshare *nn_first;
26         };
27
28
29 void get_config(void);
30 struct config config;
31
32
33 struct netnode *load_node(char *nodename)
34 {
35         FILE *fp;
36         char buf[SIZ];
37         char filename[SIZ];
38         struct netnode *newnn;
39         struct roomshare *newrs;
40
41         snprintf(filename, sizeof filename, "./network/systems/%s", nodename);
42         fp = fopen(filename, "r");
43         if (fp == NULL) {
44                 return NULL;
45                 }
46
47         newnn = (struct netnode *) malloc(sizeof(struct netnode));
48         strcpy(newnn->nn_nodename, nodename);
49         newnn->nn_first = NULL;
50
51         fgets(buf, (SIZ-1), fp);
52         buf[strlen(buf)-1] = 0;
53         strcpy(newnn->nn_spoolcmd, buf);
54
55         while (fgets(buf, (SIZ-1), fp) != NULL) {
56                 newrs = (struct roomshare *) malloc(sizeof(struct roomshare));
57                 newrs->next = newnn->nn_first;
58                 newnn->nn_first = newrs;
59                 buf[strlen(buf)-1] = 0;
60                 strcpy(newrs->rs_name, buf);
61                 fgets(buf, (SIZ-1), fp);
62                 buf[strlen(buf)-1] = 0;
63                 newrs->rs_lastsent = atol(buf);
64                 }
65
66         fclose(fp);
67         return(newnn);
68         }
69
70
71
72 void save_node(struct netnode *nnptr)
73 {
74
75         FILE *fp;
76         char filename[SIZ];
77         struct roomshare *rsptr = NULL;
78         
79         snprintf(filename, sizeof filename, "./network/systems/%s", nnptr->nn_nodename);
80         fp = fopen(filename, "w");
81         if (fp == NULL) {
82                 fprintf(stderr, "%s\n", strerror(errno));
83                 return;
84                 }
85         fprintf(fp, "%s\n", nnptr->nn_spoolcmd);
86         while (nnptr->nn_first != NULL) {
87                 fprintf(fp, "%s\n%ld\n", nnptr->nn_first->rs_name,
88                                         nnptr->nn_first->rs_lastsent);
89                 rsptr = nnptr->nn_first->next;
90                 free(nnptr->nn_first);
91                 nnptr->nn_first = rsptr;
92                 }
93         fclose(fp);
94         free(rsptr);
95         }
96
97
98
99 void display_usage(void) {
100         fprintf(stderr, "netsetup for %s\n", CITADEL);
101         fprintf(stderr, "usage: netsetup <command> [arguments]\n\n");
102         fprintf(stderr, "Commands: \n");
103         fprintf(stderr, "   nodelist                  (Lists all neighboring nodes\n");
104         fprintf(stderr, "   addnode [name]            (Adds a new node to the list)\n");
105         fprintf(stderr, "   deletenode [name]         (Deletes a node from the list)\n");
106         fprintf(stderr, "   roomlist [node]           (List rooms being shared)\n");
107         fprintf(stderr, "   getcommand [node]         (Show spool command)\n");
108         fprintf(stderr, "   setcommand [node] [cmd]   (Set spool command)\n");
109         fprintf(stderr, "   share [node] [room]       (Add a new shared room)\n");
110         fprintf(stderr, "   unshare [node] [room]     (Stop sharing a room)\n");
111         fprintf(stderr, "   help                      (Display this message)\n");
112         }
113
114
115 /*
116  * Display all neighboring nodes
117  * (This is inherently nonportable)
118  */
119 void display_nodelist(void) {
120         FILE *ls;
121         char buf[SIZ];
122
123         ls = (FILE *) popen("cd ./network/systems; ls", "r");
124         if (ls == NULL) {
125                 fprintf(stderr, "netsetup: Cannot open nodelist: %s\n",
126                         strerror(errno));
127                 exit(errno);
128                 }
129
130         while (fgets(buf, (SIZ-1), ls) != NULL) {
131                 printf("%s", buf);
132                 }
133
134         pclose(ls);
135         }
136
137
138
139 /*
140  */
141 void add_node(char *NewNodeName)
142 {
143         FILE *fp;
144         char sysfilename[SIZ];
145
146         snprintf(sysfilename, sizeof sysfilename, "./network/systems/%s", NewNodeName);
147
148         fp = fopen(sysfilename, "r");
149         if (fp != NULL) {
150                 fclose(fp);
151                 fprintf(stderr, "A node named '%s' already exists.\n",
152                         NewNodeName);
153                 exit(2);
154                 }
155
156         fp = fopen(sysfilename, "w");
157         if (fp == NULL) {
158                 fprintf(stderr, "%s\n", strerror(errno));
159                 exit(errno);
160                 }
161
162         fprintf(fp, "cat %%s >>./network/spoolout/%s\n", NewNodeName);
163         fclose(fp);
164         }
165
166
167 /*
168  */
169 void delete_node(char *NodeName)
170 {
171         FILE *fp;
172         char sysfilename[SIZ];
173         char spooloutfilename[SIZ];
174
175         snprintf(sysfilename, sizeof sysfilename, "./network/systems/%s", NodeName);
176         snprintf(spooloutfilename, sizeof spooloutfilename, "./network/spoolout/%s", NodeName);
177
178         fp = fopen(sysfilename, "r");
179         if (fp == NULL) {
180                 fprintf(stderr, "'%s' does not exist.\n",
181                         NodeName);
182                 exit(3);
183                 }
184         fclose(fp);
185
186         unlink(spooloutfilename);
187         if (unlink(sysfilename)==0) {
188                 return;
189                 }
190         fprintf(stderr, "%s\n", strerror(errno));
191         exit(errno);
192         }
193
194
195 /*
196  */
197 void do_roomlist(char *NodeName)
198 {
199         FILE *fp;
200         char sysfilename[SIZ];
201         char buf[SIZ];
202
203         snprintf(sysfilename, sizeof sysfilename, "./network/systems/%s", NodeName);
204
205         fp = fopen(sysfilename, "r");
206         if (fp == NULL) {
207                 fprintf(stderr, "'%s' does not exist.\n",
208                         NodeName);
209                 exit(3);
210                 }
211
212         fgets(buf, (SIZ-1), fp);        /* skip past spool cmd */
213         while (fgets(buf, (SIZ-1), fp) != NULL) {
214                 printf("%s", buf);
215                 fgets(buf, (SIZ-1), fp); /* skip past last-sent pointer */
216                 }
217
218         fclose(fp);
219         }
220
221
222
223 /*
224  */
225 void show_spool_cmd(char *NodeName)
226 {
227         FILE *fp;
228         char sysfilename[SIZ];
229         char buf[SIZ];
230
231         snprintf(sysfilename, sizeof sysfilename, "./network/systems/%s", NodeName);
232
233         fp = fopen(sysfilename, "r");
234         if (fp == NULL) {
235                 fprintf(stderr, "'%s' does not exist.\n",
236                         NodeName);
237                 exit(3);
238                 }
239
240         fgets(buf, (SIZ-1), fp);
241         printf("%s", buf);
242         fclose(fp);
243         }
244
245
246 /*
247  */
248 void set_spool_cmd(char *nodename, char *spoolcmd)
249 {
250         struct netnode *nnptr;
251
252         nnptr = load_node(nodename);
253         if (nnptr == NULL) {
254                 fprintf(stderr, "No such node '%s'.\n", nodename);
255                 exit(4);
256                 }
257
258         strncpy(nnptr->nn_spoolcmd, spoolcmd, (SIZ-1));
259         save_node(nnptr);
260         }
261
262
263 /*
264  */
265 void add_share(char *nodename, char *roomname)
266 {
267         struct netnode *nnptr;
268         struct roomshare *rsptr;
269         long highest = 0L;
270         int foundit = 0;
271
272         nnptr = load_node(nodename);
273         if (nnptr == NULL) {
274                 fprintf(stderr, "No such node '%s'.\n", nodename);
275                 exit(4);
276                 }
277
278         for (rsptr = nnptr->nn_first; rsptr != NULL; rsptr = rsptr->next) {
279                 if (!strcasecmp(rsptr->rs_name, roomname)) {
280                         foundit = 1;
281                         }
282                 if (rsptr->rs_lastsent > highest) {
283                         highest = rsptr->rs_lastsent;
284                         }
285                 }
286
287         if (foundit == 0) {
288                 rsptr = (struct roomshare *) malloc(sizeof(struct roomshare));
289                 rsptr->next = nnptr->nn_first;
290                 strcpy(rsptr->rs_name, roomname);
291                 rsptr->rs_lastsent = highest;
292                 nnptr->nn_first = rsptr;
293                 }
294
295         save_node(nnptr);
296         }
297
298
299 /*
300  */
301 void remove_share(char *nodename, char *roomname)
302 {
303         struct netnode *nnptr;
304         struct roomshare *rsptr, *rshold;
305         int foundit = 0;
306
307         nnptr = load_node(nodename);
308         if (nnptr == NULL) {
309                 fprintf(stderr, "No such node '%s'.\n", nodename);
310                 exit(4);
311                 }
312
313         if (nnptr->nn_first != NULL)
314            if (!strcasecmp(nnptr->nn_first->rs_name, roomname)) {
315                 rshold = nnptr->nn_first;
316                 nnptr->nn_first = nnptr->nn_first->next;
317                 free(rshold);
318                 foundit = 1;
319                 }
320
321         if (nnptr->nn_first != NULL)
322            for (rsptr = nnptr->nn_first; rsptr->next != NULL; rsptr = rsptr->next) {
323                 if (!strcasecmp(rsptr->next->rs_name, roomname)) {
324                         rshold = rsptr->next;
325                         rsptr->next = rsptr->next->next;
326                         free(rshold);
327                         foundit = 1;
328                         rsptr = nnptr->nn_first;
329                         }
330                 }
331
332         save_node(nnptr);
333
334         if (foundit == 0) {
335                 fprintf(stderr, "Not sharing '%s' with %s\n",
336                         roomname, nodename);
337                 exit(5);
338                 }
339         }
340
341
342 int main(int argc, char **argv)
343 {
344
345         if (argc < 2) {
346                 display_usage();
347                 exit(1);
348                 }
349
350         get_config();
351
352         if (!strcmp(argv[1], "help")) {
353                 display_usage();
354                 exit(0);
355                 }
356
357         if (!strcmp(argv[1], "nodelist")) {
358                 display_nodelist();
359                 exit(0);
360                 }
361
362         if (!strcmp(argv[1], "addnode")) {
363                 if (argc < 3) {
364                         display_usage();
365                         exit(1);
366                         }
367                 add_node(argv[2]);
368                 exit(0);
369                 }
370
371         if (!strcmp(argv[1], "deletenode")) {
372                 if (argc < 3) {
373                         display_usage();
374                         exit(1);
375                         }
376                 delete_node(argv[2]);
377                 exit(0);
378                 }
379
380         if (!strcmp(argv[1], "roomlist")) {
381                 if (argc < 3) {
382                         display_usage();
383                         exit(1);
384                         }
385                 do_roomlist(argv[2]);
386                 exit(0);
387                 }
388
389         if (!strcmp(argv[1], "getcommand")) {
390                 if (argc < 3) {
391                         display_usage();
392                         exit(1);
393                         }
394                 show_spool_cmd(argv[2]);
395                 exit(0);
396                 }
397
398         if (!strcmp(argv[1], "setcommand")) {
399                 if (argc < 4) {
400                         display_usage();
401                         exit(1);
402                         }
403                 set_spool_cmd(argv[2], argv[3]);
404                 exit(0);
405                 }
406
407         if (!strcmp(argv[1], "share")) {
408                 if (argc < 4) {
409                         display_usage();
410                         exit(1);
411                         }
412                 add_share(argv[2], argv[3]);
413                 exit(0);
414                 }
415
416         if (!strcmp(argv[1], "unshare")) {
417                 if (argc < 4) {
418                         display_usage();
419                         exit(1);
420                         }
421                 remove_share(argv[2], argv[3]);
422                 exit(0);
423                 }
424
425         display_usage();
426         exit(1);
427         }