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