1 #include "lsg2.h"
2 #include <string.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5
6 extern int flag_cmp(const void *, const void *);
7
lsg2_admin_validate()8 int lsg2_admin_validate()
9 {
10 char cookiebuf[BIG_BUF];
11 const char *list, *fromaddy;
12 struct list_user user;
13
14 if (!lsg2_validate(cookiebuf, sizeof(cookiebuf) - 1)) {
15 return 0;
16 }
17
18 list = LMAPI->get_var("lcgi-list");
19 fromaddy = LMAPI->get_var("lcgi-user");
20
21 if (!list || !fromaddy) {
22 lsg2_internal_error("Mode initialized incorrectly.");
23 return 0;
24 }
25
26 if (!LMAPI->user_find_list(list,fromaddy,&user)) {
27 lsg2_internal_error("Mode initialized incorrectly.");
28 return 0;
29 }
30
31 if (LMAPI->get_bool("lsg2-paranoia")) {
32 lsg2_internal_error("Attempt to use admin mode when paranoia is enabled!");
33 return 0;
34 }
35
36 if (!LMAPI->user_hasflag(&user,"ADMIN")) {
37 lsg2_internal_error("A non-admin user tried to use admin mode.");
38 return 0;
39 }
40
41 return 1;
42 }
43
CGI_MODE(cgimode_admin)44 CGI_MODE(cgimode_admin)
45 {
46 if (!lsg2_admin_validate()) {
47 return;
48 }
49
50 if (!LMAPI->cgi_unparse_template("adminmenu")) {
51 lsg2_internal_error("No 'adminmenu' template.");
52 }
53
54 return;
55 }
56
CGI_MODE(cgimode_config)57 CGI_MODE(cgimode_config)
58 {
59 if (!lsg2_admin_validate()) {
60 return;
61 }
62
63 if (!LMAPI->cgi_unparse_template("config")) {
64 lsg2_internal_error("No 'config' template.");
65 }
66
67 return;
68 }
69
CGI_HANDLER(cgihook_configfile)70 CGI_HANDLER(cgihook_configfile)
71 {
72 const char *fromaddy, *list;
73 struct list_user user;
74 struct var_data *vartemp;
75 char lastsect[BIG_BUF];
76 int counter, trusted;
77
78 fromaddy = LMAPI->get_var("lcgi-user");
79 list = LMAPI->get_var("lcgi-list");
80
81 if (!fromaddy || !list) return 0;
82
83 if (!LMAPI->user_find_list(list,fromaddy,&user))
84 return 0;
85
86 if (!LMAPI->user_hasflag(&user,"ADMIN"))
87 return 0;
88
89 trusted = LMAPI->is_trusted(list);
90
91 printf("<table border=0 width=100%%>\n");
92
93 counter = 0;
94
95 vartemp = LMAPI->start_varlist();
96
97 while (vartemp) {
98 const char *val;
99
100 if (!(vartemp->flags & VAR_LIST) || (vartemp->flags & VAR_INTERNAL)) {
101 vartemp = LMAPI->next_varlist();
102 continue;
103 }
104
105 if ((vartemp->flags & VAR_RESTRICTED) && !trusted) {
106 vartemp = LMAPI->next_varlist();
107 continue;
108 }
109
110 if (counter ? (vartemp->section ? strcasecmp(lastsect,vartemp->section) : 0 ) : 1) {
111 stringcpy(lastsect,vartemp->section);
112 if (counter) {
113 printf("<tr><td colspan=4><HR></td></tr>\n");
114 }
115 printf("<tr>\n");
116 printf("<td colspan=4><a name=\"%s\"><font size=+1><b>%s</b></font></td>\n",
117 lastsect, lastsect);
118 printf("</tr>\n");
119 }
120
121 if (!vartemp->section && lastsect[0]) {
122 lastsect[0] = 0;
123 if (counter) {
124 printf("<tr><td colspan=4><HR></td></tr>\n");
125 }
126 printf("<tr><td colspan=4><a name=\"misc\"><font size=+1><b>(Unclassified/Misc)</b></font></td></tr>\n");
127 }
128
129 counter++;
130
131 printf("<tr>\n");
132
133 val = LMAPI->get_cur_varval_level(vartemp, VAR_LIST);
134 if (val) {
135 printf(" <td valign=top><input name=\"lcgipl-%s-set\" type=checkbox",
136 vartemp->name);
137 printf(" checked=\"true\"");
138 printf("></td>\n");
139 } else {
140 val = LMAPI->get_cur_varval_level_default(vartemp, VAR_LIST);
141 printf("<td> </td>\n");
142 }
143
144 LMAPI->log_printf(18,"CGI: %s = %s\n", vartemp->name, val);
145
146 printf(" <td valign=top>%s</td>\n", vartemp->name);
147 printf(" <td valign=top>");
148
149 switch (vartemp->type) {
150 case VAR_STRING:
151 case VAR_INT:
152 case VAR_TIME:
153 printf(" <input name=\"lcgipl-%s-value\"", vartemp->name);
154 if (vartemp->type == VAR_STRING) {
155 printf(" size=30");
156 }
157 if (val) {
158 printf(" value=\"%s\"", val);
159 }
160 printf(">\n");
161 break;
162
163 case VAR_DURATION:
164 {
165 int days, hours, mins, secs;
166 int parse;
167 const char *tchr;
168
169 days = hours = mins = secs = 0;
170
171 parse = 0;
172
173 tchr = val;
174
175 while (tchr ? *tchr : 0) {
176 while (*tchr && isspace((int)(*tchr))) tchr++;
177 while (*tchr && isdigit((int)(*tchr))) { parse = parse * 10 + (*tchr - '0'); tchr++; }
178 while (*tchr && isspace((int)(*tchr))) tchr++;
179 if (*tchr) {
180 switch(*tchr) {
181 case 'd': days = parse; parse = 0; tchr++; break;
182 case 'h': hours = parse; parse = 0; tchr++; break;
183 case 'm': mins = parse; parse = 0; tchr++; break;
184 default: secs = parse; parse = 0; tchr++; break;
185 }
186 }
187 }
188
189 printf("\n <input name=\"lcgipl-%s-value-days\" value=\"%d\" size=2> d\n", vartemp->name, days);
190 printf(" <input name=\"lcgipl-%s-value-hours\" value=\"%d\" size=2> h\n", vartemp->name, hours);
191 printf(" <input name=\"lcgipl-%s-value-mins\" value=\"%d\" size=2> m\n", vartemp->name, mins);
192 printf(" <input name=\"lcgipl-%s-value-secs\" value=\"%d\" size=2> s\n ", vartemp->name, secs);
193 }
194 break;
195
196 case VAR_BOOL:
197 printf("<input type=checkbox name=\"lcgipl-%s-value\"",
198 vartemp->name);
199 if (val ? (*val == '1') : 0) {
200 printf(" checked=true");
201 }
202 printf(">");
203 break;
204
205 case VAR_CHOICE:
206 {
207 char choices[BIG_BUF], *tmpptr, *tmpptr2;
208
209 LMAPI->log_printf(18,"CGI: %s (%s)\n", vartemp->name, vartemp->choices);
210
211 printf("\n <select name=\"lcgipl-%s-value\" size=1>\n",
212 vartemp->name);
213 stringcpy(choices, vartemp->choices);
214
215 tmpptr = &choices[1];
216 while(*tmpptr) {
217 tmpptr2 = strchr(tmpptr,'|');
218 *tmpptr2++ = 0;
219
220 if (strcasecmp(tmpptr,val) == 0) {
221 printf(" <option value=\"%s\" selected> %s\n",
222 tmpptr, tmpptr);
223 } else {
224 printf(" <option value=\"%s\"> %s\n", tmpptr, tmpptr);
225 }
226
227 tmpptr = tmpptr2;
228 }
229 printf(" </select>\n");
230 }
231 break;
232
233 default:
234 printf("<b>UNSETTABLE VARIABLE! ERROR!</b>");
235 break;
236 }
237
238 printf("</td>\n");
239 if (vartemp->description) {
240 printf(" <td valign=top>%s\n",
241 vartemp->description);
242 printf("<BR> </td>\n");
243 } else {
244 printf(" <td> <BR><BR> </td>\n");
245 }
246 printf("</tr>");
247
248 vartemp = LMAPI->next_varlist();
249 }
250 LMAPI->finish_varlist();
251
252 printf("</table>\n");
253
254 return 1;
255 }
256
CGI_MODE(cgimode_setconfig)257 CGI_MODE(cgimode_setconfig)
258 {
259 char buffer[BIG_BUF];
260 const char *tempval;
261 struct var_data *var;
262 struct listserver_cgi_tempvar *cvar;
263 int override, durtotal;
264
265 durtotal = 0;
266
267 if (!lsg2_admin_validate())
268 return;
269
270 var = LMAPI->start_varlist();
271
272 while (var) {
273 if (!(var->flags & VAR_LIST) || (var->flags & VAR_INTERNAL)) {
274 var = LMAPI->next_varlist();
275 continue;
276 }
277
278 LMAPI->log_printf(18,"CGI: Config submit: checking '%s'...\n",
279 var->name);
280
281 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-set",
282 var->name);
283
284 cvar = LMAPI->find_cgi_tempvar(buffer);
285
286 tempval = LMAPI->get_cur_varval_level(var,VAR_LIST);
287
288 override = 0;
289
290 if (cvar) LMAPI->log_printf(18,"CGI: Config (%s set '%s')\n",
291 var->name, cvar->value);
292
293 if (cvar ? strcasecmp(cvar->value,"on") == 0 : !tempval) {
294 char varbuffer[BIG_BUF];
295
296 LMAPI->log_printf(18,"CGI: Entering the variable check loop...\n");
297
298 if (cvar ? strcasecmp(cvar->value,"on") == 0 : 0) override = 1;
299
300 switch(var->type) {
301 case VAR_STRING:
302 case VAR_INT:
303 case VAR_TIME:
304 case VAR_CHOICE:
305 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value",
306 var->name);
307 cvar = LMAPI->find_cgi_tempvar(buffer);
308 if (cvar) {
309 LMAPI->buffer_printf(varbuffer, sizeof(varbuffer) - 1,
310 "%s", cvar->value);
311 } else {
312 memset(varbuffer, 0, sizeof(varbuffer));
313 LMAPI->clean_var(var->name,VAR_LIST);
314 }
315 break;
316
317 case VAR_DURATION:
318 {
319 int days, hours, mins, secs;
320 char daystr[SMALL_BUF], hourstr[SMALL_BUF], minstr[SMALL_BUF], secstr[SMALL_BUF];
321
322 days = hours = mins = secs = 0;
323
324 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value-days",
325 var->name);
326 cvar = LMAPI->find_cgi_tempvar(buffer);
327 if (cvar)
328 days = atoi(cvar->value);
329 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value-hours",
330 var->name);
331 cvar = LMAPI->find_cgi_tempvar(buffer);
332 if (cvar)
333 hours = atoi(cvar->value);
334 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value-mins",
335 var->name);
336 cvar = LMAPI->find_cgi_tempvar(buffer);
337 if (cvar)
338 mins = atoi(cvar->value);
339 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value-secs",
340 var->name);
341 cvar = LMAPI->find_cgi_tempvar(buffer);
342 if (cvar)
343 secs = atoi(cvar->value);
344
345 LMAPI->buffer_printf(daystr, sizeof(daystr) - 1, "%d d ", days);
346 LMAPI->buffer_printf(hourstr, sizeof(hourstr) - 1, "%d h ", hours);
347 LMAPI->buffer_printf(minstr, sizeof(minstr) - 1, "%d m ", mins);
348 LMAPI->buffer_printf(secstr, sizeof(secstr) - 1, "%d s", secs);
349
350 durtotal = secs + (mins * 60) + (hours * 3600) +
351 (days * 86400);
352
353 LMAPI->buffer_printf(varbuffer, sizeof(varbuffer) - 1,
354 "%s%s%s%s",
355 days ? daystr : "", hours ? hourstr : "",
356 mins ? minstr : "", secs ? secstr : "");
357 }
358 break;
359
360 case VAR_BOOL:
361 LMAPI->buffer_printf(buffer, sizeof(buffer) - 1, "%s-value",
362 var->name);
363 if ((cvar = LMAPI->find_cgi_tempvar(buffer))) {
364 if (strcasecmp(cvar->value,"on") == 0) {
365 LMAPI->buffer_printf(varbuffer, sizeof(varbuffer) - 1, "true");
366 } else {
367 LMAPI->buffer_printf(varbuffer, sizeof(varbuffer) - 1, "false");
368 }
369 } else {
370 LMAPI->buffer_printf(varbuffer, sizeof(varbuffer) - 1, "false");
371 }
372 break;
373
374 default:
375 break;
376 }
377
378 if (!override) {
379 const char *val;
380
381 val = LMAPI->get_cur_varval_level(var,VAR_LIST);
382
383 if (!val) {
384 val = LMAPI->get_cur_varval_level_default(var,VAR_LIST);
385
386 LMAPI->log_printf(18, "CGI: %s = %s (now %s)\n",
387 var->name, val, varbuffer);
388
389 if (val) {
390 switch (var->type) {
391 case VAR_STRING:
392 case VAR_CHOICE:
393 if (strcasecmp(val,varbuffer) != 0) {
394 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
395 }
396 break;
397
398 case VAR_INT:
399 case VAR_TIME:
400 if (LMAPI->get_number(var->name) != atoi(varbuffer)) {
401 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
402 }
403 break;
404
405 case VAR_BOOL:
406 LMAPI->log_printf(18,"CGI: %s: %d / %d\n",
407 var->name, LMAPI->get_bool(var->name),
408 (strcasecmp("true",varbuffer) == 0));
409 if (LMAPI->get_bool(var->name) !=
410 (strcasecmp("true",varbuffer) == 0)) {
411 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
412 }
413 break;
414
415 case VAR_DURATION:
416 if (LMAPI->get_seconds(var->name) != durtotal) {
417 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
418 }
419 break;
420
421 default:
422 break;
423 }
424 } else {
425 if (varbuffer[0]) {
426 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
427 }
428 }
429 } else {
430 LMAPI->clean_var(var->name,VAR_LIST);
431 }
432 } else {
433 LMAPI->set_var(var->name,varbuffer,VAR_LIST);
434 }
435 } else {
436 LMAPI->clean_var(var->name,VAR_LIST);
437 }
438
439 var = LMAPI->next_varlist();
440 }
441
442 LMAPI->finish_varlist();
443
444 LMAPI->log_printf(18,"CGI: strip-mdn = %s\n",
445 LMAPI->get_bool("strip-mdn") ? "true" : "false");
446
447 LMAPI->listdir_file(buffer,LMAPI->get_string("lcgi-list"),"config");
448 LMAPI->write_configfile(buffer,VAR_LIST,NULL);
449
450 LMAPI->log_printf(1,"CGI: %s: %s sent new config\n",
451 LMAPI->get_string("lcgi-list"), LMAPI->get_string("lcgi-user"));
452
453 if (!LMAPI->cgi_unparse_template("adminmenu")) {
454 lsg2_internal_error("No 'adminmenu' template.");
455 }
456
457 return;
458 }
459
CGI_MODE(cgimode_getfile)460 CGI_MODE(cgimode_getfile)
461 {
462 const char *getfile;
463 struct list_file *tfile;
464
465 if (!lsg2_admin_validate()) {
466 return;
467 }
468
469 getfile = LMAPI->get_var("lcgi-adminfile");
470 if (!getfile) {
471 lsg2_internal_error("Mode initialized wrong.");
472 return;
473 }
474
475 tfile = LMAPI->find_file(getfile);
476 if (!tfile) {
477 lsg2_internal_error("Attempt to retrieve a nonexistant file.");
478 return;
479 }
480
481 LMAPI->set_var("tlcgi-editfile", LMAPI->get_var(tfile->varname),
482 VAR_TEMP);
483
484 LMAPI->set_var("tlcgi-editfile-desc", tfile->desc, VAR_TEMP);
485
486 if (!LMAPI->cgi_unparse_template("fileedit")) {
487 lsg2_internal_error("No 'fileedit' template.");
488 }
489
490 return;
491 }
492
file_cmp(const void * e1,const void * e2)493 int file_cmp(const void *e1, const void *e2)
494 {
495 struct list_file *f1, *f2;
496 f1 = *(struct list_file **)e1;
497 f2 = *(struct list_file **)e2;
498
499 return (strcasecmp(f1->name,f2->name));
500 }
501
CGI_HANDLER(cgihook_adminfilelistdrop)502 CGI_HANDLER(cgihook_adminfilelistdrop)
503 {
504 struct list_file *tfile;
505 struct list_file **filearr;
506 int counter, i;
507
508 tfile = LMAPI->get_files();
509
510 counter = 0;
511
512 while (tfile) {
513 tfile = tfile->next;
514 counter++;
515 }
516
517
518 filearr = (struct list_file **)malloc(sizeof(struct list_file *) * counter);
519
520 tfile = LMAPI->get_files();
521 for (i = 0; i < counter; i++) {
522 filearr[i] = tfile;
523 tfile = tfile->next;
524 }
525
526 qsort(filearr,counter,sizeof(struct list_file *),file_cmp);
527
528 printf("<select name=\"lcgi-adminfile\" size=6>\n");
529
530 for (i = 0; i < counter; i++) {
531 if (!(filearr[i]->flags & FILE_NOWEBEDIT))
532 printf("<option value=\"%s\"> %s\n", filearr[i]->name,
533 filearr[i]->name);
534 }
535 printf("</select>\n");
536
537 free(filearr);
538
539 return 1;
540 }
541
CGI_HANDLER(cgihook_fileedit)542 CGI_HANDLER(cgihook_fileedit)
543 {
544 const char *filepath;
545 FILE *infile;
546 char buffer[BIG_BUF];
547
548 filepath = LMAPI->get_var("tlcgi-editfile");
549 if (!filepath) return 0;
550
551 LMAPI->listdir_file(buffer,LMAPI->get_string("lcgi-list"),filepath);
552
553 infile = LMAPI->open_file(buffer,"r");
554
555 printf("<textarea name=\"lcgipl-textbody\" rows=18 cols=76 wrap=physical>");
556
557 if (infile) {
558 while(LMAPI->read_file(buffer, sizeof(buffer), infile)) {
559 printf("%s",buffer);
560 }
561 LMAPI->close_file(infile);
562 } else {
563 printf("** File was empty **\n");
564 }
565 printf("</textarea>");
566
567 return 1;
568 }
569
CGI_MODE(cgimode_putfile)570 CGI_MODE(cgimode_putfile)
571 {
572 const char *getfile;
573 struct list_file *tfile;
574 FILE *outfile;
575 char buffer[BIG_BUF];
576 struct listserver_cgi_tempvar *cvar;
577
578 if (!lsg2_admin_validate()) {
579 return;
580 }
581
582 getfile = LMAPI->get_var("lcgi-adminfile");
583 if (!getfile) {
584 lsg2_internal_error("Mode initialized wrong.");
585 return;
586 }
587
588 LMAPI->log_printf(18,"CGI: Made it into putfile...\n");
589
590 tfile = LMAPI->find_file(getfile);
591 if (!tfile) {
592 lsg2_internal_error("Attempt to replace a nonexistant file.");
593 return;
594 }
595
596 cvar = LMAPI->find_cgi_tempvar("textbody");
597
598 if (!cvar) {
599 /* The entire textbox contents were deleted... the file is gone */
600
601 LMAPI->listdir_file(buffer,LMAPI->get_string("lcgi-list"),
602 LMAPI->get_string(tfile->varname));
603 LMAPI->unlink_file(buffer);
604 return;
605 }
606
607 LMAPI->log_printf(18,"CGI: We have our textbody...\n");
608
609 LMAPI->listdir_file(buffer,LMAPI->get_string("lcgi-list"),LMAPI->get_string(tfile->varname));
610
611 LMAPI->log_printf(18,"CGI: Attempting to put file %s\n", buffer);
612
613 if ((outfile = LMAPI->open_file(buffer,"w")) == NULL) {
614 lsg2_internal_error("File access error.");
615 return;
616 }
617
618 LMAPI->write_file(outfile,"%s",cvar->value);
619 LMAPI->close_file(outfile);
620
621 LMAPI->log_printf(1,"CGI: %s: %s replaced '%s' \n",
622 LMAPI->get_string("lcgi-list"), LMAPI->get_string("lcgi-user"),
623 tfile->name);
624
625 if (!LMAPI->cgi_unparse_template("adminmenu")) {
626 lsg2_internal_error("No 'adminmenu' template.");
627 }
628
629 return;
630 }
631
CGI_MODE(cgimode_admin_subscribe)632 CGI_MODE(cgimode_admin_subscribe)
633 {
634 char userfile[BIG_BUF];
635 char tempbuf[BIG_BUF];
636 const char *from;
637 char *inputbuffer, *ptr1, *ptr2;
638 struct listserver_cgi_tempvar *cvar;
639
640 if (!lsg2_admin_validate()) {
641 return;
642 }
643
644 from = LMAPI->get_var("lcgi-user");
645
646 cvar = LMAPI->find_cgi_tempvar("subscribe-userlist");
647
648 if (!cvar) {
649 lsg2_internal_error("No users provided.");
650 }
651
652 inputbuffer = strdup(cvar->value);
653
654 LMAPI->set_var("adminmode","true",VAR_GLOBAL);
655 LMAPI->set_var("fromaddress",from,VAR_GLOBAL);
656 LMAPI->set_var("realsender",from,VAR_GLOBAL);
657
658 ptr1 = inputbuffer;
659
660
661 while(ptr1 && *ptr1) {
662 char *tptr;
663
664 while(isspace((int)(*ptr1))) ptr1++;
665
666 ptr2 = strchr(ptr1,'\n');
667
668 tptr = NULL;
669
670 if (ptr2) {
671 *ptr2++ = 0;
672 if (*ptr2 == 0x0d) *ptr2++ = 0;
673 }
674
675 tptr = strchr(ptr1,0x0d);
676 if (tptr) *tptr = 0;
677
678 if (!strlen(ptr1) || !strchr(ptr1,'@') || !strchr(ptr1,'.')) {
679 ptr1 = ptr2;
680 continue;
681 }
682
683 LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "subscribe %s",
684 ptr1);
685 LMAPI->set_var("cur-parse-line", tempbuf, VAR_GLOBAL);
686 LMAPI->set_var("subscribe-me",ptr1,VAR_GLOBAL);
687
688 if (LMAPI->do_hooks("PRESUB") == HOOK_RESULT_FAIL) {
689 ptr1 = ptr2;
690 continue;
691 }
692
693 LMAPI->listdir_file(userfile,LMAPI->get_string("list"),"users");
694
695 if (LMAPI->user_add(userfile,ptr1)) {
696 LMAPI->spit_status("Filesystem error while subscribing user.");
697 ptr1 = ptr2;
698 continue;
699 }
700
701 LMAPI->log_printf(0, "%s subscribed to %s by %s\n",ptr1,
702 LMAPI->get_string("listname"),from);
703
704 LMAPI->do_hooks("POSTSUB");
705
706 ptr1 = ptr2;
707 }
708
709 LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s.perr");
710 if (LMAPI->exists_file(tempbuf)) {
711 LMAPI->set_var("tlcgi-textfile",tempbuf,VAR_TEMP);
712 if (!LMAPI->cgi_unparse_template("textfile")) {
713 lsg2_internal_error("No 'textfile' template.");
714 }
715 LMAPI->unlink_file(tempbuf);
716 return;
717 }
718
719 if (!LMAPI->cgi_unparse_template("adminmenu")) {
720 lsg2_internal_error("No 'adminmenu' template.");
721 }
722
723 return;
724 }
725
CGI_MODE(cgimode_admin_unsubscribe)726 CGI_MODE(cgimode_admin_unsubscribe)
727 {
728 char userfile[BIG_BUF];
729 const char *from, *userfor;
730 char tempbuf[BIG_BUF];
731
732 if (!lsg2_admin_validate()) {
733 return;
734 }
735
736 from = LMAPI->get_var("lcgi-user");
737 userfor = LMAPI->get_var("lcgi-userfor");
738
739 LMAPI->set_var("adminmode","true",VAR_GLOBAL);
740
741 if (!userfor) {
742 lsg2_internal_error("Mode initialized wrong.");
743 return;
744 }
745
746 LMAPI->set_var("subscribe-me",userfor,VAR_GLOBAL);
747 LMAPI->set_var("fromaddress",from,VAR_GLOBAL);
748 LMAPI->set_var("realsender",from,VAR_GLOBAL);
749
750 if (LMAPI->do_hooks("PREUNSUB") == HOOK_RESULT_FAIL) {
751 char tempbuf[BIG_BUF];
752
753 LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s.perr",
754 LMAPI->get_string("queuefile"));
755 LMAPI->set_var("tlcgi-textfile",tempbuf,VAR_TEMP);
756 if (!LMAPI->cgi_unparse_template("textfile")) {
757 lsg2_internal_error("No textfile template.");
758 }
759 return;
760 }
761
762 LMAPI->listdir_file(userfile,LMAPI->get_string("list"),"users");
763
764 if (LMAPI->user_remove(userfile,userfor)) {
765 lsg2_internal_error("Filesystem error while unsubscribing user.");
766 LMAPI->filesys_error(userfile);
767 LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s.perr",
768 LMAPI->get_string("queuefile"));
769 LMAPI->unlink_file(tempbuf);
770 return;
771 }
772
773 LMAPI->log_printf(0, "%s unsubscribed from %s by %s\n",userfor,
774 LMAPI->get_string("listname"),from);
775
776 LMAPI->do_hooks("POSTUNSUB");
777
778 if (!LMAPI->cgi_unparse_template("adminmenu")) {
779 lsg2_internal_error("No 'adminmenu' template.");
780 return;
781 }
782
783 return;
784 }
785
CGI_MODE(cgimode_admin_setflags)786 CGI_MODE(cgimode_admin_setflags)
787 {
788 struct list_user user;
789 const char *list, *fromaddy;
790 struct listserver_flag *tflag;
791 int isadmin;
792 char tbuf[BIG_BUF];
793
794 if (!lsg2_admin_validate()) {
795 return;
796 }
797
798 list = LMAPI->get_var("lcgi-list");
799 fromaddy = LMAPI->get_var("lcgi-userfor");
800
801 LMAPI->set_var("realsender",LMAPI->get_var("lcgi-user"),VAR_GLOBAL);
802 LMAPI->set_var("fromaddress",LMAPI->get_var("lcgi-user"),VAR_GLOBAL);
803
804 if (!list || !fromaddy) {
805 lsg2_internal_error("Invalid state for flag setting.");
806 }
807
808 if (!LMAPI->user_find_list(list, fromaddy, &user)) {
809 char errbuf[BIG_BUF];
810
811 LMAPI->buffer_printf(errbuf, sizeof(errbuf) - 1, "%s is not a member of %s",
812 fromaddy, list);
813
814 lsg2_internal_error(errbuf);
815 }
816
817 isadmin = LMAPI->user_hasflag(&user,"ADMIN");
818
819 tflag = LMAPI->get_flags();
820 while (tflag) {
821 if (!strcasecmp(tflag->name,"superadmin") ||
822 (tflag->admin & ADMIN_UNSETTABLE)) {
823 tflag = tflag->next;
824 continue;
825 }
826
827 if (LMAPI->find_cgi_tempvar(tflag->name)) {
828 LMAPI->log_printf(18,"CGI: %s is selected.\n", tflag->name);
829 if (!LMAPI->user_hasflag(&user,tflag->name)) {
830 LMAPI->set_var("setflag-user",user.address,VAR_TEMP);
831 LMAPI->set_var("setflag-flag",tflag->name,VAR_TEMP);
832 if (LMAPI->do_hooks("SETFLAG") != HOOK_RESULT_FAIL) {
833 /* Re-read the user in case they were modified by the
834 * hooks. */
835 LMAPI->user_find_list(list,fromaddy,&user);
836 if (!LMAPI->user_hasflag(&user,tflag->name)) {
837 char userlistfile[BIG_BUF];
838
839 LMAPI->listdir_file(userlistfile, list, "users");
840 LMAPI->user_setflag(&user,tflag->name,1);
841 LMAPI->user_write(userlistfile, &user);
842 }
843 }
844 }
845 } else {
846 LMAPI->log_printf(18,"CGI: %s is unselected.\n", tflag->name);
847 if (LMAPI->user_hasflag(&user,tflag->name)) {
848 LMAPI->set_var("setflag-user",user.address,VAR_TEMP);
849 LMAPI->set_var("setflag-flag",tflag->name,VAR_TEMP);
850 if (LMAPI->do_hooks("UNSETFLAG") != HOOK_RESULT_FAIL) {
851 /* Re-read the user in case they were modified by the
852 * hooks. */
853 LMAPI->user_find_list(list,fromaddy,&user);
854 if (LMAPI->user_hasflag(&user,tflag->name)) {
855 char userlistfile[BIG_BUF];
856
857 LMAPI->listdir_file(userlistfile, list, "users");
858 LMAPI->user_unsetflag(&user,tflag->name,1);
859 LMAPI->user_write(userlistfile, &user);
860 }
861 }
862 }
863 }
864 tflag = tflag->next;
865 }
866
867 LMAPI->buffer_printf(tbuf, sizeof(tbuf) - 1, "%s.perr",
868 LMAPI->get_string("queuefile"));
869
870 if (LMAPI->exists_file(tbuf)) {
871 LMAPI->set_var("tlcgi-textfile",tbuf,VAR_TEMP);
872 if (!LMAPI->cgi_unparse_template("textfile")) {
873 lsg2_internal_error("No 'textfile' template.");
874 }
875 LMAPI->unlink_file(tbuf);
876 } else {
877 if (!LMAPI->cgi_unparse_template("admin-userinfo")) {
878 lsg2_internal_error("No 'admin-userinfo' template.");
879 }
880 }
881 }
882
CGI_MODE(cgimode_admin_setname)883 CGI_MODE(cgimode_admin_setname)
884 {
885 const char *list, *user, *name;
886
887 if (!lsg2_admin_validate()) {
888 return;
889 }
890
891 list = LMAPI->get_var("lcgi-list");
892 user = LMAPI->get_var("lcgi-userfor");
893 name = LMAPI->get_var("lcgi-fullname");
894
895 if (!list || !user || !name) {
896 lsg2_internal_error("Mode not initialized properly.");
897 return;
898 }
899
900 LMAPI->userstat_set_stat(list,user,"realname",name);
901
902 if (!LMAPI->cgi_unparse_template("admin-userinfo")) {
903 lsg2_internal_error("No 'admin-userinfo' template.");
904 }
905
906 return;
907 }
908
CGI_MODE(cgimode_admin_userinfo)909 CGI_MODE(cgimode_admin_userinfo)
910 {
911 const char *list, *user;
912
913 if (!lsg2_admin_validate()) {
914 return;
915 }
916
917 list = LMAPI->get_var("lcgi-list");
918 user = LMAPI->get_var("lcgi-userfor");
919
920 if (!list || !user) {
921 lsg2_internal_error("Mode not initialized properly.");
922 return;
923 }
924
925 if (!LMAPI->cgi_unparse_template("admin-userinfo")) {
926 lsg2_internal_error("No 'admin-userinfo' template.");
927 }
928
929 return;
930 }
931
CGI_MODE(cgimode_admin_usersetinfo)932 CGI_MODE(cgimode_admin_usersetinfo)
933 {
934 const char *list, *user, *target;
935 struct list_user realuser, realtarget;
936
937 if (!lsg2_admin_validate()) {
938 return;
939 }
940
941 list = LMAPI->get_var("lcgi-list");
942 user = LMAPI->get_var("lcgi-user");
943 target = LMAPI->get_var("lcgi-userfor");
944
945 if (!list || !user) {
946 lsg2_internal_error("Mode not initialized properly.");
947 return;
948 }
949
950 if (LMAPI->user_find_list(list,target,&realtarget)) {
951 if (LMAPI->user_find_list(list,user,&realuser)) {
952
953 if (LMAPI->user_hasflag(&realtarget,"ADMIN") &&
954 !LMAPI->user_hasflag(&realuser,"SUPERADMIN")) {
955 lsg2_internal_error("You are not a SUPERADMIN and cannot alter options on other admins.");
956 return;
957 }
958 }
959 }
960
961 if (!LMAPI->cgi_unparse_template("admin-usersetinfo")) {
962 lsg2_internal_error("No 'admin-usersetinfo' template.");
963 }
964
965 return;
966 }
967
CGI_MODE(cgimode_admin_userfor_generic)968 CGI_MODE(cgimode_admin_userfor_generic)
969 {
970 if (!lsg2_admin_validate()) {
971 return;
972 }
973
974 if (LMAPI->find_cgi_tempvar("unsubscribe")) {
975 cgimode_admin_unsubscribe();
976 return;
977 }
978
979 if (LMAPI->find_cgi_tempvar("userinfo")) {
980 cgimode_admin_userinfo();
981 return;
982 }
983
984 if (LMAPI->find_cgi_tempvar("usersetinfo")) {
985 cgimode_admin_usersetinfo();
986 }
987 }
988
CGI_HANDLER(cgihook_admin_flaglist)989 CGI_HANDLER(cgihook_admin_flaglist)
990 {
991 int cols, curcol;
992 struct listserver_flag *tflag;
993 struct listserver_flag **flagarr;
994 struct list_user user;
995 int isadmin, counter, i;
996
997 cols = 2;
998
999 if (param && *param) {
1000 cols = atoi(param);
1001 if (!cols) cols = 2;
1002 }
1003
1004 if (cols < 1) cols = 1;
1005
1006 tflag = LMAPI->get_flags();
1007
1008 curcol = 1;
1009
1010 if (!LMAPI->user_find_list(LMAPI->get_string("lcgi-list"),
1011 LMAPI->get_string("lcgi-userfor"), &user)) {
1012 printf("<b>You are not subscribed to this list.</b>");
1013 return 0;
1014 }
1015
1016 isadmin = LMAPI->user_hasflag(&user,"ADMIN");
1017
1018 printf("<table border=0 width=100%%>\n");
1019 printf(" <tr>\n");
1020
1021 counter = 0;
1022
1023 while(tflag) {
1024 counter++;
1025 tflag = tflag->next;
1026 }
1027
1028 flagarr = (struct listserver_flag **)malloc(sizeof(struct listserver_flag *) * counter);
1029
1030 tflag = LMAPI->get_flags();
1031
1032 for (i = 0; i < counter; i++) {
1033 flagarr[i] = tflag;
1034 tflag = tflag->next;
1035 }
1036
1037 qsort(flagarr,counter,sizeof(struct listserver_flag *),flag_cmp);
1038
1039 for (i = 0; i < counter; i++) {
1040 if (!curcol) curcol = 1;
1041
1042 tflag = flagarr[i];
1043
1044 if (strcasecmp(tflag->name,"superadmin") ||
1045 !(tflag->admin & ADMIN_UNSETTABLE)) {
1046
1047 printf(" <td valign=top width=%d%%>\n", 100 / cols);
1048 printf(" <input type=\"checkbox\" name=\"lcgipl-%s\"",
1049 tflag->name);
1050 if (LMAPI->user_hasflag(&user,tflag->name)) {
1051 printf(" checked=\"true\"");
1052 }
1053 printf("> %s\n", tflag->name);
1054 printf(" <ul>%s</ul>\n", tflag->desc);
1055 printf(" </td>");
1056
1057 curcol++;
1058
1059 if (curcol > cols) {
1060 printf(" </tr>\n<tr>\n");
1061 curcol = 0;
1062 }
1063 }
1064 }
1065
1066 if (curcol != 0) {
1067 while(curcol < cols) {
1068 printf(" <td> </td>\n");
1069 curcol++;
1070 }
1071 printf(" </tr>\n");
1072 }
1073
1074 free(flagarr);
1075
1076 printf("</table>");
1077 return 1;
1078 }
1079
CGI_HANDLER(cgihook_admin_setname)1080 CGI_HANDLER(cgihook_admin_setname)
1081 {
1082 char fullname[256];
1083 const char *user, *list;
1084
1085 user = LMAPI->get_var("lcgi-userfor");
1086 list = LMAPI->get_var("lcgi-list");
1087
1088 if (!user || !list) return 0;
1089
1090 if (LMAPI->userstat_get_stat(list,user,"realname",&fullname[0],255)) {
1091 printf("<input name=\"lcgi-fullname\" length=255 value=\"%s\">\n",
1092 fullname);
1093 } else {
1094 printf("<input name=\"lcgi-fullname\" length=255>\n");
1095 }
1096 printf("<input name=\"lcgi-userfor\" type=hidden value=\"%s\">\n",
1097 LMAPI->get_var("lcgi-userfor"));
1098
1099 return 1;
1100 }
1101
CGI_HANDLER(cgihook_admin_showflags)1102 CGI_HANDLER(cgihook_admin_showflags)
1103 {
1104 int cols, curcol, width;
1105 struct listserver_flag *tflag;
1106 struct listserver_flag **flagarr;
1107 struct list_user user;
1108 int counter, i;
1109
1110 cols = 2;
1111 width = 100;
1112
1113 if (param && *param) {
1114 char *parseme;
1115 char unparse[BIG_BUF];
1116
1117 stringcpy(unparse,param);
1118
1119 if ((parseme = strchr(unparse,','))) {
1120 *parseme++ = 0;
1121 width = atoi(parseme);
1122 }
1123 cols = atoi(unparse);
1124 if (!cols) cols = 2;
1125 }
1126
1127 if (cols < 1) cols = 1;
1128 if (width > 100) width = 100;
1129 if (width < 0) width = 0;
1130
1131 tflag = LMAPI->get_flags();
1132
1133 curcol = 1;
1134
1135 if (!LMAPI->user_find_list(LMAPI->get_string("lcgi-list"),
1136 LMAPI->get_string("lcgi-userfor"), &user)) {
1137 printf("<b>%s is not subscribed to this list.</b>",
1138 LMAPI->get_string("lcgi-userfor"));
1139 return 0;
1140 }
1141
1142 counter = 0;
1143
1144 while(tflag) {
1145 counter++;
1146 tflag = tflag->next;
1147 }
1148
1149 flagarr = (struct listserver_flag **)malloc(sizeof(struct listserver_flag *) * counter);
1150
1151 tflag = LMAPI->get_flags();
1152
1153 for (i = 0; i < counter; i++) {
1154 flagarr[i] = tflag;
1155 tflag = tflag->next;
1156 }
1157
1158 qsort(flagarr,counter,sizeof(struct listserver_flag *),flag_cmp);
1159
1160 printf("<table border=0");
1161 if (width) {
1162 printf(" width=%d%%", width);
1163 }
1164 printf(">\n");
1165 printf(" <tr>\n");
1166
1167 for(i = 0; i < counter; i++) {
1168 if (!curcol) curcol = 1;
1169 tflag = flagarr[i];
1170 if (!LMAPI->user_hasflag(&user,tflag->name)) {
1171 tflag = tflag->next;
1172 continue;
1173 }
1174
1175 printf(" <td valign=top>\n");
1176 printf("<b>%s</b>\n", tflag->name);
1177 printf(" </td><td valign=top>\n");
1178 printf(" %s\n", tflag->desc);
1179 printf(" </td>");
1180
1181 tflag = tflag->next;
1182 curcol++;
1183
1184 if (curcol > cols) {
1185 printf(" </tr>\n<tr>\n");
1186 curcol = 0;
1187 }
1188 }
1189
1190 if (curcol != 0) {
1191 while(curcol < cols) {
1192 printf(" <td> </td><td> </td>\n");
1193 curcol++;
1194 }
1195 printf(" </tr>\n");
1196 }
1197
1198 free(flagarr);
1199
1200 printf("</table>");
1201 return 1;
1202 }
1203
1204 /*
1205 * kjh: qsort compare function for e-mail addresses
1206 */
user_compare(const void * p1,const void * p2)1207 static int user_compare(const void *p1, const void *p2)
1208 {
1209 /* convert params to their "real" type */
1210 const char *u1 = (const char *) *((const char **) p1);
1211 const char *u2 = (const char *) *((const char **) p2);
1212 /* parse out the domain */
1213 const char *domain1 = strchr(u1, '@');
1214 const char *domain2 = strchr(u2, '@');
1215 int rv = 0;
1216
1217 /* skip past the '@' sign, otherwise make sure that we have an ptr to a
1218 * deferenceable string (just in case there wasn't a domain)
1219 */
1220 if (domain1 != 0)
1221 domain1++;
1222 else
1223 domain1 = "";
1224
1225 if (domain2 != 0)
1226 domain2++;
1227 else
1228 domain2 = "";
1229
1230 rv = strcasecmp(domain1, domain2); /* compare the domain */
1231
1232 // if (rv == 0) /* if same domain, compare user */
1233 rv = strcasecmp(u1, u2);
1234
1235 return rv;
1236 }
1237
1238
1239
CGI_HANDLER(cgihook_admin_userlistbox)1240 CGI_HANDLER(cgihook_admin_userlistbox)
1241 {
1242 FILE *infile;
1243 char filename[BIG_BUF];
1244 struct list_user user;
1245 int n_users = 256;
1246 const char **users = 0;
1247 int n = 0;
1248
1249 LMAPI->listdir_file(filename,LMAPI->get_string("lcgi-list"),"users");
1250
1251 if ((infile = LMAPI->open_file(filename,"r")) == NULL)
1252 return 0;
1253
1254 printf("<select name=\"lcgi-userfor\"");
1255 if (param) {
1256 int size;
1257
1258 size = atoi(param);
1259 if (size < 1) size = 1;
1260 printf(" size=%d", size);
1261 } else {
1262 printf(" size=20");
1263 }
1264 printf(">\n");
1265
1266 if (LMAPI->get_bool("lsg2-sort-userlist")) {
1267 users = (const char **)malloc(n_users * sizeof(char *));
1268
1269 while(LMAPI->user_read(infile,&user)) {
1270 if (n == n_users) {
1271 n_users *= 2;
1272 users = realloc((void*)users, n_users*sizeof(char *));
1273 }
1274 users[n++] = strdup(user.address);
1275 }
1276
1277 /* kjh: sort users by e-mail address */
1278 qsort((void*)users, n, sizeof(const char *), user_compare);
1279
1280 {
1281 const char **userp;
1282 for (userp = users; userp < users+n; userp++) {
1283 printf("<option value=\"%s\"> %s\n",
1284 *userp, *userp);
1285 free((char *) *userp);
1286 }
1287 }
1288 free((void*)users);
1289 }
1290 else {
1291 while(LMAPI->user_read(infile,&user)) {
1292 printf("<option value=\"%s\"> %s\n",
1293 user.address, user.address);
1294 }
1295 printf("</select>\n");
1296 }
1297
1298 printf("</select>\n");
1299
1300
1301 return 1;
1302 }
1303
1304