* add contexttype, so the subst can precheck the context pointer for us, and bad...
[citadel.git] / webcit / netconf.c
1 /* 
2  * $Id$
3  */
4 /**
5  * \defgroup NetShareConf Functions which handle network and sharing configuration.
6  *
7  * \ingroup CitadelConfig
8  */
9 /*@{*/
10 #include "webcit.h"
11
12 void display_netconf(void);
13
14 /*----------------------------------------------------------------------*/
15 /*              Business Logic                                          */
16 /*----------------------------------------------------------------------*/
17
18 typedef struct _nodeconf {
19         int DeleteMe;
20         StrBuf *NodeName;
21         StrBuf *Secret;
22         StrBuf *Host;
23         StrBuf *Port;
24 }NodeConf;
25
26 void DeleteNodeConf(void *vNode)
27 {
28         NodeConf *Node = (NodeConf*) vNode;
29         FreeStrBuf(&Node->NodeName);
30         FreeStrBuf(&Node->Secret);
31         FreeStrBuf(&Node->Host);
32         FreeStrBuf(&Node->Port);
33         free(Node);
34 }
35
36 NodeConf *NewNode(StrBuf *SerializedNode)
37 {
38         NodeConf *Node;
39
40         if (StrLength(SerializedNode) < 8) 
41                 return NULL; /** we need at least 4 pipes and some other text so its invalid. */
42         Node = (NodeConf *) malloc(sizeof(NodeConf));
43         Node->DeleteMe = 0;
44         Node->NodeName=NewStrBuf();
45         StrBufExtract_token(Node->NodeName, SerializedNode, 0, '|');
46         Node->Secret=NewStrBuf();
47         StrBufExtract_token(Node->Secret, SerializedNode, 1, '|');
48         Node->Host=NewStrBuf();
49         StrBufExtract_token(Node->Host, SerializedNode, 2, '|');
50         Node->Port=NewStrBuf();
51         StrBufExtract_token(Node->Port, SerializedNode, 3, '|');
52         return Node;
53 }
54
55 NodeConf *HttpGetNewNode(void)
56 {
57         NodeConf *Node;
58
59         if (!havebstr("node") || 
60             !havebstr("secret")||
61             !havebstr("host")||
62             !havebstr("port"))
63                 return NULL;
64
65         Node = (NodeConf *) malloc(sizeof(NodeConf));
66         Node->DeleteMe = 0;
67         Node->NodeName = NewStrBufDup(sbstr("node"));
68         Node->Secret = NewStrBufDup(sbstr("secret"));
69         Node->Host = NewStrBufDup(sbstr("host"));
70         Node->Port = NewStrBufDup(sbstr("port"));
71         return Node;
72 }
73
74 void SerializeNode(NodeConf *Node, StrBuf *Buf)
75 {
76         StrBufPrintf(Buf, "%s|%s|%s|%s", 
77                      ChrPtr(Node->NodeName),
78                      ChrPtr(Node->Secret),
79                      ChrPtr(Node->Host),
80                      ChrPtr(Node->Port));
81 }
82
83
84 HashList *load_netconf(WCTemplateToken *Token)
85 {
86         StrBuf *Buf;
87         HashList *Hash;
88         char nnn[64];
89         char buf[SIZ];
90         long len;
91         int nUsed;
92         NodeConf *Node;
93
94         serv_puts("CONF getsys|application/x-citadel-ignet-config");
95         serv_getln(buf, sizeof buf);
96         if (buf[0] == '1') {
97                 Hash = NewHash(1, NULL);
98
99                 Buf = NewStrBuf();
100                 while ((len = StrBuf_ServGetln(Buf),
101                         strcmp(ChrPtr(Buf), "000"))) {
102                         Node = NewNode(Buf);
103                         if (Node == NULL)
104                                 continue;
105                         nUsed = GetCount(Hash);
106                         nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
107                         Put(Hash, nnn, nUsed, Node, DeleteNodeConf); 
108                 }
109                 FreeStrBuf(&Buf);
110                 return Hash;
111         }
112         return NULL;
113 }
114
115
116 void NodeCfgSubst(StrBuf *TemplBuffer, void *vContext, WCTemplateToken *Token)
117 {
118         NodeConf *Node= (NodeConf*)vContext;
119
120         SVPutBuf("CFG:IGNET:NODE", Node->NodeName, 1);
121         SVPutBuf("CFG:IGNET:SECRET", Node->Secret, 1);
122         SVPutBuf("CFG:IGNET:HOST", Node->Host, 1);
123         SVPutBuf("CFG:IGNET:PORT", Node->Port, 1);
124 }
125
126
127 void save_net_conf(HashList *Nodelist)
128 {
129         char buf[SIZ];
130         StrBuf *Buf;
131         HashPos *where;
132         void *vNode;
133         NodeConf *Node;
134         const char *Key;
135         long KeyLen;
136
137         serv_puts("CONF putsys|application/x-citadel-ignet-config");
138         serv_getln(buf, sizeof buf);
139         if (buf[0] == '4') {
140                 if ((Nodelist != NULL) && (GetCount(Nodelist) > 0)) {
141                         where = GetNewHashPos();
142                         Buf = NewStrBuf();
143                         while (GetNextHashPos(Nodelist, where, &KeyLen, &Key, &vNode)) {
144                                 Node = (NodeConf*) vNode;
145                                 if (Node->DeleteMe==0) { 
146                                         SerializeNode(Node, Buf);
147                                         serv_putbuf(Buf);
148                                 }
149                         }
150                         FreeStrBuf(&Buf);
151                 }
152                 serv_puts("000");
153         }
154 }
155
156
157
158 /*----------------------------------------------------------------------*/
159 /*              WEB Handlers                                            */
160 /*----------------------------------------------------------------------*/
161
162
163
164 /**
165  * \brief edit a network node
166  */
167 void edit_node(void) {
168         HashList *NodeConfig;
169         const StrBuf *Index;
170         NodeConf *NewNode;
171 /*
172         char buf[SIZ];
173         char node[SIZ];
174         char cnode[SIZ];
175         FILE *fp;
176 */
177         if (havebstr("ok_button")) {
178                 Index = sbstr("index");
179                 NewNode = HttpGetNewNode();
180                 if ((NewNode == NULL) || (Index == NULL)) {
181                         sprintf(WC->ImportantMessage, _("Invalid Parameter"));
182                         url_do_template();
183                         return;
184                 }
185                         
186                 NodeConfig = load_netconf(NULL);
187                 Put(NodeConfig, ChrPtr(Index), StrLength(Index), NewNode, DeleteNodeConf);
188                 save_net_conf(NodeConfig);
189                 DeleteHash(&NodeConfig);
190 /*
191                 strcpy(node, bstr("node") );
192                 fp = tmpfile();
193                 if (fp != NULL) {
194                         serv_puts("CONF getsys|application/x-citadel-ignet-config");
195                         serv_getln(buf, sizeof buf);
196                         if (buf[0] == '1') {
197                                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
198                                         extract_token(cnode, buf, 0, '|', sizeof cnode);
199                                         if (strcasecmp(node, cnode)) {
200                                                 fprintf(fp, "%s\n", buf);
201                                         }
202                                 }
203                         rewind(fp);
204                 }
205
206                 serv_puts("CONF putsys|application/x-citadel-ignet-config");
207                 serv_getln(buf, sizeof buf);
208                 if (buf[0] == '4') {
209                         if (fp != NULL) {
210                                 while (fgets(buf, sizeof buf, fp) != NULL) {
211                                         buf[strlen(buf)-1] = 0;
212                                         if (buf[0] != 0) {
213                                                 serv_puts(buf);
214                                         }
215                                 }
216                                 fclose(fp);
217                         }
218                         serv_printf("%s|%s|%s|%s", 
219                                 bstr("node"),
220                                 bstr("secret"),
221                                 bstr("host"),
222                                 bstr("port") );
223                         }
224                         serv_puts("000");
225                 }
226 */
227         }
228
229         //display_netconf();
230         url_do_template();
231 }
232
233
234 /**
235  * \brief add a node
236  */
237 void display_add_node(void)
238 {/*
239         output_headers(1, 1, 2, 0, 0, 0);
240         wprintf("<div id=\"banner\">\n");
241         wprintf("<h1>");
242         wprintf(_("Add a new node"));
243         wprintf("</h1>");
244         wprintf("</div>\n");
245
246         wprintf("<div id=\"content\" class=\"service\">\n");
247
248         wprintf("<FORM METHOD=\"POST\" action=\"edit_node\">\n");
249         wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
250         wprintf("<CENTER><TABLE border=0>\n");
251         wprintf("<TR><TD>%s</TD>", _("Node name"));
252         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"node\" MAXLENGTH=\"16\"></TD></TR>\n");
253         wprintf("<TR><TD>%s</TD>", _("Shared secret"));
254         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"secret\" MAXLENGTH=\"16\"></TD></TR>\n");
255         wprintf("<TR><TD>%s</TD>", _("Host or IP address"));
256         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"host\" MAXLENGTH=\"64\"></TD></TR>\n");
257         wprintf("<TR><TD>%s</TD>", _("Port number"));
258         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"port\" VALUE=\"504\" MAXLENGTH=\"8\"></TD></TR>\n");
259         wprintf("</TABLE><br />");
260         wprintf("<INPUT TYPE=\"submit\" NAME=\"ok_button\" VALUE=\"%s\">", _("Add node"));
261         wprintf("&nbsp;");
262         wprintf("<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">", _("Cancel"));
263         wprintf("</CENTER></FORM>\n");
264
265         wDumpContent(1);
266  */
267 }
268
269 /**
270  * \brief modify an existing node
271  */
272 void display_edit_node(void)
273 {
274         HashList *NodeConfig;
275         const StrBuf *Index;
276         void *vNode;
277
278         Index = sbstr("index");
279         if (Index == NULL) {
280                 sprintf(WC->ImportantMessage, _("Invalid Parameter"));
281                 url_do_template();
282                 return;
283         }
284
285         NodeConfig = load_netconf(NULL);
286         if (!GetHash(NodeConfig, ChrPtr(Index), StrLength(Index), &vNode) || 
287             (vNode == NULL)) {
288                 sprintf(WC->ImportantMessage, _("Invalid Parameter"));
289                 url_do_template();
290                 DeleteHash(&NodeConfig);
291                 return;
292         }
293         
294         NodeCfgSubst(NULL, vNode, NULL);
295         SVPutBuf("ITERATE:KEY", Index, 1);
296         url_do_template();
297
298         DeleteHash(&NodeConfig);
299         
300 /*
301         char buf[512];
302         char node[256];
303         char cnode[256];
304         char csecret[256];
305         char chost[256];
306         char cport[256];
307
308         strcpy(node, bstr("node"));
309
310         output_headers(1, 1, 2, 0, 0, 0);
311         wprintf("<div id=\"banner\">\n");
312         wprintf("<h1>");
313         wprintf(_("Edit node configuration for "));
314         escputs(node);
315         wprintf("</h1>");
316         wprintf("</div>\n");
317
318         wprintf("<div id=\"content\" class=\"service\">\n");
319
320         serv_puts("CONF getsys|application/x-citadel-ignet-config");
321         serv_getln(buf, sizeof buf);
322         if (buf[0] == '1') {
323                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
324                         extract_token(cnode, buf, 0, '|', sizeof cnode);
325                         extract_token(csecret, buf, 1, '|', sizeof csecret);
326                         extract_token(chost, buf, 2, '|', sizeof chost);
327                         extract_token(cport, buf, 3, '|', sizeof cport);
328
329                         if (!strcasecmp(node, cnode)) {
330                                 wprintf("<FORM METHOD=\"POST\" action=\"edit_node\">\n");
331                                 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
332                                 wprintf("<CENTER><TABLE border=0>\n");
333                                 wprintf("<TR><TD>");
334                                 wprintf(_("Node name"));
335                                 wprintf("</TD>");
336                                 wprintf("<TD><INPUT TYPE=\"text\" NAME=\"node\" MAXLENGTH=\"16\" VALUE=\"%s\"></TD></TR>\n", cnode);
337                                 wprintf("<TR><TD>");
338                                 wprintf(_("Shared secret"));
339                                 wprintf("</TD>");
340                                 wprintf("<TD><INPUT TYPE=\"password\" NAME=\"secret\" MAXLENGTH=\"16\" VALUE=\"%s\"></TD></TR>\n", csecret);
341                                 wprintf("<TR><TD>");
342                                 wprintf(_("Host or IP address"));
343                                 wprintf("</TD>");
344                                 wprintf("<TD><INPUT TYPE=\"text\" NAME=\"host\" MAXLENGTH=\"64\" VALUE=\"%s\"></TD></TR>\n", chost);
345                                 wprintf("<TR><TD>");
346                                 wprintf(_("Port number"));
347                                 wprintf("</TD>");
348                                 wprintf("<TD><INPUT TYPE=\"text\" NAME=\"port\" MAXLENGTH=\"8\" VALUE=\"%s\"></TD></TR>\n", cport);
349                                 wprintf("</TABLE><br />");
350                                 wprintf("<INPUT TYPE=\"submit\" NAME=\"ok_button\" VALUE=\"%s\">",
351                                         _("Save changes"));
352                                 wprintf("&nbsp;");
353                                 wprintf("<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">",
354                                         _("Cancel"));
355                                 wprintf("</CENTER></FORM>\n");
356                         }
357
358                 }
359         }
360
361         else {          / ** command error getting configuration * /
362                 wprintf("%s<br />\n", &buf[4]);
363         }
364
365         wDumpContent(1);
366 */
367 }
368
369
370
371
372 //CFG:IGNET:NODE
373 /**
374  * \brief display all configured nodes
375  */
376 void display_netconf(void)
377 {
378 /*
379         char buf[SIZ];
380         char node[SIZ];
381         output_headers(1, 1, 2, 0, 0, 0);
382         wprintf("<div id=\"banner\">\n");
383         wprintf("<h1>");
384         wprintf(_("Network configuration"));
385         wprintf("</h1>");
386         wprintf("</div>\n");
387
388         wprintf("<div id=\"content\" class=\"service\">\n");
389
390         wprintf("<CENTER>");
391         wprintf("<a href=\"display_add_node\">");
392         wprintf(_("Add a new node"));
393         wprintf("</A><br />\n");
394         wprintf("</CENTER>");
395
396         wprintf("<TABLE class=\"netconf_banner\"><TR><TD>");
397         wprintf("<SPAN CLASS=\"titlebar\">");
398         wprintf(_("Currently configured nodes"));
399         wprintf("</SPAN>\n");
400         wprintf("</TD></TR></TABLE>\n");
401         serv_puts("CONF getsys|application/x-citadel-ignet-config");
402         serv_getln(buf, sizeof buf);
403         if (buf[0] == '1') {
404                 wprintf("<CENTER><TABLE border=0>\n");
405                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
406                         extract_token(node, buf, 0, '|', sizeof node);
407                         wprintf("<TR><TD><FONT SIZE=+1>");
408                         escputs(node);
409                         wprintf("</FONT></TD>");
410                         wprintf("<TD><a href=\"display_edit_node&node=");
411                         urlescputs(node);
412                         wprintf("\">");
413                         wprintf(_("(Edit)"));
414                         wprintf("</A></TD>");
415                         wprintf("<TD><a href=\"display_confirm_delete_node&node=");
416                         urlescputs(node);
417                         wprintf("\">");
418                         wprintf(_("(Delete)"));
419                         wprintf("</A></TD>");
420                         wprintf("</TR>\n");
421                 }
422                 wprintf("</TABLE></CENTER>\n");
423         }
424 */
425         wDumpContent(1);
426 }
427
428 /**
429  * \brief display the dialog to verify the deletion
430  */
431 void display_confirm_delete_node(void)
432 {
433 /*
434         char node[SIZ];
435         output_headers(1, 1, 2, 0, 0, 0);
436         wprintf("<div id=\"banner\">\n");
437         wprintf("<h1>");
438         wprintf(_("Confirm delete"));
439         wprintf("</h1>");
440         wprintf("</div>\n");
441
442         wprintf("<div id=\"content\" class=\"service\" >\n");
443
444         strcpy(node, bstr("node"));
445         wprintf("<CENTER>");
446         wprintf(_("Are you sure you want to delete "));
447         wprintf("<FONT SIZE=+1>");
448         escputs(node);
449         wprintf("</FONT>?<br />\n");
450         wprintf("<a href=\"delete_node&node=");
451         urlescputs(node);
452         wprintf("\">");
453         wprintf(_("Yes"));
454         wprintf("</A>&nbsp;&nbsp;&nbsp;");
455         wprintf("<a href=\"display_netconf\">");
456         wprintf(_("No"));
457         wprintf("</A><br />\n");
458 */
459         wDumpContent(1);
460 }
461
462
463 /**
464  * \brief actually delete the node
465  */
466 void delete_node(void)
467 {
468         HashList *NodeConfig;
469         const StrBuf *Index;
470         NodeConf *Node;
471         void *vNode;
472
473         Index = sbstr("index");
474         if (Index == NULL) {
475                 sprintf(WC->ImportantMessage, _("Invalid Parameter"));
476                 url_do_template();
477                 return;
478         }
479
480         NodeConfig = load_netconf(NULL);
481         if (!GetHash(NodeConfig, ChrPtr(Index), StrLength(Index), &vNode) || 
482             (vNode == NULL)) {
483                 sprintf(WC->ImportantMessage, _("Invalid Parameter"));
484                 url_do_template();
485                 DeleteHash(&NodeConfig);
486                 return;
487         }
488         Node = (NodeConf *) vNode;
489         Node->DeleteMe = 1;
490         save_net_conf(NodeConfig);
491         DeleteHash(&NodeConfig);
492         
493         url_do_template();
494
495 /*
496         char buf[SIZ];
497         char node[SIZ];
498         char cnode[SIZ];
499         FILE *fp;
500
501         strcpy(node, bstr("node") );
502         fp = tmpfile();
503         if (fp != NULL) {
504                 serv_puts("CONF getsys|application/x-citadel-ignet-config");
505                 serv_getln(buf, sizeof buf);
506                 if (buf[0] == '1') {
507                         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
508                                 extract_token(cnode, buf, 0, '|', sizeof cnode);
509                                 if (strcasecmp(node, cnode)) {
510                                         fprintf(fp, "%s\n", buf);
511                                 }
512                         }
513                 }
514                 rewind(fp);
515
516                 serv_puts("CONF putsys|application/x-citadel-ignet-config");
517                 serv_getln(buf, sizeof buf);
518                 if (buf[0] == '4') {
519                         while (fgets(buf, sizeof buf, fp) != NULL) {
520                                 buf[strlen(buf)-1] = 0;
521                                 serv_puts(buf);
522                         }
523                         serv_puts("000");
524                 }
525                 fclose(fp);
526         }
527
528         display_netconf();
529 */
530 }
531
532 void 
533 InitModule_NETCONF
534 (void)
535 {
536         WebcitAddUrlHandler(HKEY("display_edit_node"), display_edit_node, 0);
537
538         WebcitAddUrlHandler(HKEY("edit_node"), edit_node, 0);
539         WebcitAddUrlHandler(HKEY("display_netconf"), display_netconf, 0);
540         WebcitAddUrlHandler(HKEY("display_confirm_delete_node"), display_confirm_delete_node, 0);
541         WebcitAddUrlHandler(HKEY("delete_node"), delete_node, 0);
542         WebcitAddUrlHandler(HKEY("display_add_node"), display_add_node, 0);
543         RegisterIterator("NODECONFIG", 0, NULL, load_netconf, NodeCfgSubst, DeleteHash, CTX_NODECONF);
544 }
545 /*@}*/