1 #include <stdlib.h>
2 #include <string.h>
3 
4 #include "lsg2.h"
5 
flag_cmp(const void * e1,const void * e2)6 int flag_cmp(const void *e1, const void *e2)
7 {
8    struct listserver_flag *f1, *f2;
9 
10    f1 = *(struct listserver_flag **)e1;
11    f2 = *(struct listserver_flag **)e2;
12 
13    return (strcasecmp(f1->name,f2->name));
14 }
15 
CGI_HANDLER(cgihook_modehead)16 CGI_HANDLER(cgihook_modehead)
17 {
18   printf("<form action=\"%s\" method=post>\n",
19     LMAPI->get_string("lsg2-cgi-url"));
20   printf("<input type=hidden name=\"lcgi-mode\" value=\"%s\">\n", param);
21   if (LMAPI->get_var("lcgi-mode")) {
22      printf("<input type=hidden name=\"lcgi-lastmode\" value=\"%s\">\n",
23       LMAPI->get_var("lcgi-mode"));
24   }
25   return 1;
26 }
27 
CGI_HANDLER(cgihook_modeheadex)28 CGI_HANDLER(cgihook_modeheadex)
29 {
30   printf("<form action=\"%s\" method=post>\n",
31     LMAPI->get_string("lsg2-cgi-url"));
32   printf("<input type=hidden name=\"lcgi-mode\" value=\"%s\">\n", param);
33 
34   if (LMAPI->get_var("lcgi-mode")) {
35      printf("<input type=hidden name=\"lcgi-lastmode\" value=\"%s\">\n",
36       LMAPI->get_var("lcgi-mode"));
37   }
38 
39   if (LMAPI->get_var("lcgi-user")) {
40     printf("<input name=\"lcgi-user\" type=hidden value=\"%s\">\n", LMAPI->get_var("lcgi-user"));
41   }
42 
43   if (LMAPI->get_var("lcgi-cookie")) {
44     printf("<input name=\"lcgi-cookie\" type=hidden value=\"%s\">\n",
45       LMAPI->get_var("lcgi-cookie"));
46   }
47 
48   if (LMAPI->get_var("list")) {
49     printf("<input name=\"lcgi-list\" type=hidden value=\"%s\">\n",
50       LMAPI->get_string("list"));
51   }
52 
53   return 1;
54 }
55 
CGI_HANDLER(cgihook_modeend)56 CGI_HANDLER(cgihook_modeend)
57 {
58   printf("</form>\n");
59   return 1;
60 }
61 
CGI_HANDLER(cgihook_editusername)62 CGI_HANDLER(cgihook_editusername)
63 {
64   printf("<input name=\"lcgi-user\"");
65   if (LMAPI->get_var("lcgi-user")) {
66     printf("value=\"%s\" ", LMAPI->get_var("lcgi-user"));
67   }
68   if (param ? atoi(param) : 0) {
69     printf("length=%d", atoi(param));
70   }
71   printf(">\n");
72   return 1;
73 }
74 
CGI_HANDLER(cgihook_username)75 CGI_HANDLER(cgihook_username)
76 {
77   printf("<input name=\"lcgi-user\"");
78   if (LMAPI->get_var("lcgi-user")) {
79     printf(" type=hidden value=\"%s\"", LMAPI->get_var("lcgi-user"));
80   }
81   else if (param ? atoi(param) : 0) {
82     printf(" length=%d", atoi(param));
83   }
84   printf(">\n");
85   return 1;
86 }
87 
CGI_HANDLER(cgihook_authcookie)88 CGI_HANDLER(cgihook_authcookie)
89 {
90   printf("<input name=\"lcgi-cookie\"");
91   if (LMAPI->get_var("lcgi-cookie")) {
92     printf("type=hidden value=\"%s\" ", LMAPI->get_var("lcgi-cookie"));
93   }
94   else if (param ? atoi(param) : 0) {
95     printf("length=%d", atoi(param));
96   }
97   printf(">\n");
98   return 1;
99 }
100 
CGI_HANDLER(cgihook_password)101 CGI_HANDLER(cgihook_password)
102 {
103   printf("<input type=password name=\"lcgi-pass\"");
104   if (param ? atoi(param) : 0) {
105     printf("length=%d", atoi(param));
106   }
107   printf(">\n");
108   return 1;
109 }
110 
CGI_HANDLER(cgihook_submit)111 CGI_HANDLER(cgihook_submit)
112 {
113   printf("<input type=submit");
114   if (param) {
115     printf(" value=\"%s\"", param);
116   }
117   printf(">\n");
118   return 1;
119 }
120 
lsg2_lists_selectbox()121 void lsg2_lists_selectbox()
122 {
123   int status;
124   char dname[BIG_BUF];
125   struct list_user user;
126 
127    printf("<select name=\"lcgi-list\" size=1>\n");
128 
129    if (!(status = LMAPI->walk_lists(&dname[0]))) {
130        printf("<option value=\".uhoh.\">-- Unable to access lists --\n");
131    } else {
132        while (status) {
133           if(LMAPI->list_valid(dname)) {
134               LMAPI->clean_var("advertise", VAR_TEMP);
135               LMAPI->read_conf_parm(dname,"advertise", VAR_TEMP);
136               if (LMAPI->user_find_list(dname,LMAPI->get_string("lcgi-user"),&user)) {
137                  printf("\t<option value=\"%s\"> %s (Subscribed)\n",
138                    dname, dname);
139               } else {
140                  if (LMAPI->get_bool("advertise")) {
141                     printf("\t<option value=\"%s\"> %s\n", dname, dname);
142                  }
143               }
144               LMAPI->clean_var("advertise", VAR_TEMP);
145           }
146           status = LMAPI->next_lists(&dname[0]);
147        }
148    }
149    printf("</select>\n");
150 }
151 
lsg2_lists_selectboxex(int listsize)152 void lsg2_lists_selectboxex(int listsize)
153 {
154   int status;
155   char dname[BIG_BUF];
156   struct list_user user;
157   int count = listsize;
158 
159    if (count == 0) {
160       status = LMAPI->walk_lists(&dname[0]);
161       if (!status) {
162          printf("<option value=\".uhoh.\">-- Unable to access lists --\n");
163       }
164 
165       while (status) {
166          if (LMAPI->list_valid(&dname[0])) count++;
167          status = LMAPI->next_lists(&dname[0]);
168       }
169    }
170 
171    printf("<select name=\"lcgi-list\" size=%d>\n", count);
172 
173    if (!(status = LMAPI->walk_lists(&dname[0]))) {
174        printf("<option value=\".uhoh.\">-- Unable to access lists --\n");
175    } else {
176        while (status) {
177           if(LMAPI->list_valid(dname)) {
178               LMAPI->clean_var("advertise", VAR_TEMP);
179               LMAPI->read_conf_parm(dname,"advertise", VAR_TEMP);
180               if (LMAPI->user_find_list(dname,LMAPI->get_string("lcgi-user"),&user)) {
181                  printf("\t<option value=\"%s\"> %s (Subscribed)\n",
182                    dname, dname);
183               } else {
184                  if (LMAPI->get_bool("advertise")) {
185                     printf("\t<option value=\"%s\"> %s\n", dname, dname);
186                  }
187               }
188               LMAPI->clean_var("advertise", VAR_TEMP);
189           }
190           status = LMAPI->next_lists(&dname[0]);
191        }
192    }
193    printf("</select>\n");
194 }
195 
CGI_HANDLER(cgihook_lists)196 CGI_HANDLER(cgihook_lists)
197 {
198    lsg2_lists_selectbox();
199    return 1;
200 }
201 
CGI_HANDLER(cgihook_listsex)202 CGI_HANDLER(cgihook_listsex)
203 {
204    lsg2_lists_selectboxex(param ? atoi(param) : 0);
205    return 1;
206 }
207 
CGI_HANDLER(cgihook_display_textfile)208 CGI_HANDLER(cgihook_display_textfile)
209 {
210    if (LMAPI->get_var("tlcgi-textfile")) {
211       lsg2_html_textfile(LMAPI->get_string("tlcgi-textfile"));
212    }
213    return 1;
214 }
215 
CGI_HANDLER(cgihook_welcome_button)216 CGI_HANDLER(cgihook_welcome_button)
217 {
218    char tempfile[BIG_BUF];
219 
220    LMAPI->listdir_file(tempfile,LMAPI->get_string("lcgi-list"),
221       LMAPI->get_string("welcome-file"));
222 
223    if (LMAPI->exists_file(tempfile))
224       printf("<input type=submit name=\"lcgipl-show-welcome\" value=\"Intro File\">\n");
225    return 1;
226 }
227 
CGI_HANDLER(cgihook_faq_button)228 CGI_HANDLER(cgihook_faq_button)
229 {
230    char tempfile[BIG_BUF];
231 
232    LMAPI->listdir_file(tempfile,LMAPI->get_string("lcgi-list"),
233       LMAPI->get_string("faq-file"));
234 
235    if (LMAPI->exists_file(tempfile))
236       printf("<input type=submit name=\"lcgipl-show-faq\" value=\"FAQ\">\n");
237    return 1;
238 }
239 
CGI_HANDLER(cgihook_infofile_button)240 CGI_HANDLER(cgihook_infofile_button)
241 {
242    char tempfile[BIG_BUF];
243 
244    LMAPI->listdir_file(tempfile,LMAPI->get_string("lcgi-list"),
245       LMAPI->get_string("info-file"));
246 
247    if (LMAPI->exists_file(tempfile))
248       printf("<input type=submit name=\"lcgipl-show-info\" value=\"List Info File\">\n");
249    return 1;
250 }
251 
CGI_HANDLER(cgihook_curlist)252 CGI_HANDLER(cgihook_curlist)
253 {
254    if (LMAPI->get_var("list")) {
255      printf("<input type=hidden name=\"lcgi-list\" value=\"%s\">",
256        LMAPI->get_string("list"));
257    }
258    return 1;
259 }
260 
display_user(const char * format,struct list_user * user)261 void display_user(const char *format, struct list_user *user)
262 {
263    char output[BIG_BUF], output2[BIG_BUF];
264    char tempbuf[BIG_BUF];
265    const char *list;
266 
267    list = LMAPI->get_string("list");
268 
269    LMAPI->strreplace(output, sizeof(output) - 1,format,"%u",user->address);
270    stringcpy(output2, output);
271 
272 
273    if (LMAPI->userstat_get_stat(list,user->address,"realname", tempbuf, sizeof(tempbuf) - 1)) {
274       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%n",tempbuf);
275    } else {
276       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%n","");
277    }
278    stringcpy(output2, output);
279 
280    if (LMAPI->userstat_get_stat(list,user->address,"traffic", tempbuf, sizeof(tempbuf) - 1)) {
281       char temp[SMALL_BUF];
282 
283       LMAPI->buffer_printf(temp, sizeof(temp) - 1, "%sk", tempbuf);
284       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%t",temp);
285    } else {
286       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%t","");
287    }
288    stringcpy(output2, output);
289 
290    if (LMAPI->userstat_get_stat(list,user->address,"posts", tempbuf, sizeof(tempbuf) - 1)) {
291       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%P",tempbuf);
292    } else {
293       LMAPI->strreplace(output, sizeof(output) - 1,output2,"%P","");
294    }
295    stringcpy(output2, output);
296 
297    if (LMAPI->userstat_get_stat(list,user->address,"position", tempbuf, sizeof(tempbuf) - 1)) {
298      LMAPI->strreplace(output, sizeof(output) - 1,output2,"%p",tempbuf);
299    } else {
300      LMAPI->strreplace(output, sizeof(output) - 1,output2,"%p","");
301    }
302    stringcpy(output2, output);
303 
304    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%d",
305      LMAPI->user_hasflag(user,"DIGEST") ? "DIGEST" : "");
306    stringcpy(output2, output);
307 
308    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%D",
309      LMAPI->user_hasflag(user,"DIGEST") ?
310      LMAPI->get_string("lsg2-img-digest") : "");
311    stringcpy(output2, output);
312 
313    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%a",
314      LMAPI->user_hasflag(user,"ADMIN") ? "ADMIN" : "");
315    stringcpy(output2, output);
316 
317    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%A",
318      LMAPI->user_hasflag(user,"ADMIN") ?
319      LMAPI->get_string("lsg2-img-admin") : "");
320    stringcpy(output2, output);
321 
322    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%h",
323      LMAPI->user_hasflag(user,"HIDDEN") ? "HIDDEN" : "");
324    stringcpy(output2, output);
325 
326    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%H",
327      LMAPI->user_hasflag(user,"HIDDEN") ?
328      LMAPI->get_string("lsg2-img-hidden") : "");
329    stringcpy(output2, output);
330 
331    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%m",
332      LMAPI->user_hasflag(user,"MODERATOR") ? "MODERATOR" : "");
333    stringcpy(output2, output);
334 
335    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%M",
336      LMAPI->user_hasflag(user,"MODERATOR") ?
337      LMAPI->get_string("lsg2-img-moderator") : "");
338    stringcpy(output2, output);
339 
340    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%v",
341      LMAPI->user_hasflag(user,"VACATION") ? "VACATION" : "");
342    stringcpy(output2, output);
343 
344    LMAPI->strreplace(output, sizeof(output) - 1,output2,"%V",
345      LMAPI->user_hasflag(user,"VACATION") ?
346      LMAPI->get_string("lsg2-img-vacation") : "");
347 
348    printf("%s\n",output);
349 }
350 
CGI_HANDLER(cgihook_userlist)351 CGI_HANDLER(cgihook_userlist)
352 {
353    char tempbuffer[BIG_BUF];
354    int isadmin, allow=0;
355    const char *list;
356    struct list_user user;
357    FILE *userfile;
358    unsigned long total, admins, moderators, digest, hidden, vacation;
359 
360    list = LMAPI->get_string("lcgi-list");
361 
362 // CHANGES RW
363 // HATES IT! MURDER! DEATH! KILL!
364 
365    if (strcmp(LMAPI->get_string("who-status"),"public") == 0)
366      { allow=1; }
367    if ((LMAPI->user_find_list(list,LMAPI->get_string("lcgi-user"), &user)) &&
368        (strcmp(LMAPI->get_string("who-status"),"private") == 0))
369      { allow=1; }
370    if (LMAPI->user_hasflag(&user,"ADMIN"))
371      { allow=1;
372        isadmin=1;
373      }
374      else { isadmin=0; }
375 
376    if (allow == 0)
377      { printf("<B>Permission denied.</b>");
378        return 1;
379      }
380 
381    LMAPI->listdir_file(tempbuffer,list,"users");
382 
383    if ((userfile = LMAPI->open_file(tempbuffer,"r")) == NULL) {
384       printf("<B>permission denied.</b>");
385    }
386 
387    total = admins = moderators = digest = hidden = vacation = 0;
388 
389    while(LMAPI->user_read(userfile,&user)) {
390       total++;
391       if (LMAPI->user_hasflag(&user,"ADMIN")) admins++;
392       if (LMAPI->user_hasflag(&user,"MODERATORS")) moderators++;
393       if (LMAPI->user_hasflag(&user,"DIGEST")) digest++;
394       if (LMAPI->user_hasflag(&user,"HIDDEN")) hidden++;
395       if (LMAPI->user_hasflag(&user,"VACATION")) vacation++;
396 
397       if (!LMAPI->user_hasflag(&user,"HIDDEN") || isadmin)
398          display_user(param,&user);
399    }
400 
401    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", total);
402    LMAPI->set_var("tlcgi-users-total",tempbuffer,VAR_TEMP);
403 
404    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", admins);
405    LMAPI->set_var("tlcgi-users-admins",tempbuffer,VAR_TEMP);
406 
407    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", moderators);
408    LMAPI->set_var("tlcgi-users-moderators",tempbuffer,VAR_TEMP);
409 
410    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", hidden);
411    LMAPI->set_var("tlcgi-users-hidden",tempbuffer,VAR_TEMP);
412 
413    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", digest);
414    LMAPI->set_var("tlcgi-users-digest",tempbuffer,VAR_TEMP);
415 
416    LMAPI->buffer_printf(tempbuffer, sizeof(tempbuffer) - 1, "%lu", vacation);
417    LMAPI->set_var("tlcgi-users-vacation",tempbuffer,VAR_TEMP);
418 
419    return 1;
420 }
421 
CGI_HANDLER(cgihook_liscript)422 CGI_HANDLER(cgihook_liscript)
423 {
424    char tempbuffer[BIG_BUF];
425    char escape[BIG_BUF];
426 
427    if (!param) return 1;
428 
429    LMAPI->strreplace(tempbuffer, sizeof(tempbuffer) - 1,param,"{","[");
430    stringcpy(escape, tempbuffer);
431    LMAPI->strreplace(tempbuffer, sizeof(tempbuffer) - 1,escape,"}","]");
432    stringcpy(escape, tempbuffer);
433 
434    if (LMAPI->liscript_parse_line(escape, tempbuffer, sizeof(tempbuffer) - 1)) {
435       printf("%s",tempbuffer);
436    }
437 
438    return 1;
439 }
440 
CGI_HANDLER(cgihook_subscribe)441 CGI_HANDLER(cgihook_subscribe)
442 {
443   if (!LMAPI->get_var("lcgi-cookie") || !LMAPI->get_var("lcgi-user") ||
444       !LMAPI->get_var("list")) return 1;
445 
446   printf("<form action=\"%s\" method=post>\n",
447     LMAPI->get_string("lsg2-cgi-url"));
448   printf("<input name=\"lcgi-user\" type=hidden value=\"%s\">\n", LMAPI->get_var("lcgi-user"));
449   printf("<input name=\"lcgi-cookie\" type=hidden value=\"%s\">\n",
450     LMAPI->get_var("lcgi-cookie"));
451   printf("<input name=\"lcgi-list\" type=hidden value=\"%s\">\n",
452     LMAPI->get_string("list"));
453   printf("<input type=hidden name=\"lcgi-mode\" value=\"subscribe\">\n");
454   if (param && *param)
455     printf("<input type=submit value=\"%s\">\n", param);
456   else
457     printf("<input type=submit value=\"Subscribe\">\n");
458   printf("</form>\n");
459   return 1;
460 }
461 
CGI_HANDLER(cgihook_unsubscribe)462 CGI_HANDLER(cgihook_unsubscribe)
463 {
464   if (!LMAPI->get_var("lcgi-cookie") || !LMAPI->get_var("lcgi-user") ||
465       !LMAPI->get_var("list")) return 1;
466 
467   printf("<form action=\"%s\" method=post>\n",
468     LMAPI->get_string("lsg2-cgi-url"));
469   printf("<input name=\"lcgi-user\" type=hidden value=\"%s\">\n", LMAPI->get_var("lcgi-user"));
470   printf("<input name=\"lcgi-cookie\" type=hidden value=\"%s\">\n",
471     LMAPI->get_var("lcgi-cookie"));
472   printf("<input name=\"lcgi-list\" type=hidden value=\"%s\">\n",
473     LMAPI->get_string("list"));
474   printf("<input type=hidden name=\"lcgi-mode\" value=\"unsubscribe\">\n");
475   if (param && *param)
476     printf("<input type=submit value=\"%s\">\n", param);
477   else
478     printf("<input type=submit value=\"Unsubscribe\">\n");
479   printf("</form>\n");
480   return 1;
481 }
482 
CGI_HANDLER(cgihook_flaglist)483 CGI_HANDLER(cgihook_flaglist)
484 {
485   int cols, curcol;
486   struct listserver_flag *tflag;
487   struct listserver_flag **flagarr;
488   struct list_user user;
489   int isadmin, counter, i;
490 
491   cols = 2;
492 
493   if (param && *param) {
494     cols = atoi(param);
495     if (!cols) cols = 2;
496   }
497 
498   if (cols < 1) cols = 1;
499 
500   tflag = LMAPI->get_flags();
501 
502   curcol = 1;
503 
504   if (!LMAPI->user_find_list(LMAPI->get_string("lcgi-list"),
505         LMAPI->get_string("lcgi-user"), &user)) {
506      printf("<b>You are not subscribed to this list.</b>");
507      return 0;
508   }
509 
510   isadmin = LMAPI->user_hasflag(&user,"ADMIN");
511 
512   printf("<table border=0 width=100%%>\n");
513   printf(" <tr>\n");
514 
515   counter = 0;
516 
517   while(tflag) {
518      counter++;
519      tflag = tflag->next;
520   }
521 
522   flagarr = (struct listserver_flag **)malloc(sizeof(struct listserver_flag *) * counter);
523 
524   tflag = LMAPI->get_flags();
525 
526   for (i = 0; i < counter; i++) {
527      flagarr[i] = tflag;
528      tflag = tflag->next;
529   }
530 
531   qsort(flagarr,counter,sizeof(struct listserver_flag *),flag_cmp);
532 
533   for (i = 0; i < counter; i++) {
534      if (!curcol) curcol = 1;
535 
536      tflag = flagarr[i];
537 
538      if (!strcasecmp(tflag->name,"superadmin") ||
539         (tflag->admin & ADMIN_UNSAFE) ||
540         (tflag->admin & ADMIN_UNSETTABLE) ||
541         (tflag->admin && !isadmin)) {
542         tflag = tflag->next;
543         continue;
544      }
545 
546      printf("  <td valign=top width=%d%%>\n", 100 / cols);
547      printf("   <input type=\"checkbox\" name=\"lcgipl-%s\"",
548        tflag->name);
549      if (LMAPI->user_hasflag(&user,tflag->name)) {
550        printf(" checked=\"true\"");
551      }
552      printf("> %s\n", tflag->name);
553      printf("   <ul>%s</ul>\n", tflag->desc);
554      printf("  </td>");
555 
556      tflag = tflag->next;
557      curcol++;
558 
559      if (curcol > cols) {
560         printf(" </tr>\n<tr>\n");
561         curcol = 0;
562      }
563   }
564 
565   if (curcol != 0) {
566      while(curcol < cols) {
567         printf("  <td>&nbsp;</td>\n");
568         curcol++;
569      }
570      printf(" </tr>\n");
571   }
572 
573   free(flagarr);
574 
575   printf("</table>");
576   return 1;
577 }
578 
CGI_HANDLER(cgihook_setname)579 CGI_HANDLER(cgihook_setname)
580 {
581   char fullname[256];
582   const char *user, *list;
583 
584   user = LMAPI->get_var("lcgi-user");
585   list = LMAPI->get_var("lcgi-list");
586 
587   if (!user || !list) return 0;
588 
589   if (LMAPI->userstat_get_stat(list,user,"realname",&fullname[0],255)) {
590      printf("<input name=\"lcgi-fullname\" length=255 value=\"%s\">\n",
591         fullname);
592   } else {
593      printf("<input name=\"lcgi-fullname\" length=255>\n");
594   }
595 
596   return 1;
597 }
598 
CGI_HANDLER(cgihook_showflags)599 CGI_HANDLER(cgihook_showflags)
600 {
601   int cols, curcol, width;
602   struct listserver_flag *tflag;
603   struct listserver_flag **flagarr;
604   struct list_user user;
605   int counter, i;
606 
607   cols = 2;
608   width = 100;
609 
610   if (param && *param) {
611     char *parseme;
612     char unparse[BIG_BUF];
613 
614     stringcpy(unparse, param);
615 
616     if ((parseme = strchr(unparse,','))) {
617        *parseme++ = 0;
618        width = atoi(parseme);
619     }
620     cols = atoi(unparse);
621     if (!cols) cols = 2;
622   }
623 
624   if (cols < 1) cols = 1;
625   if (width > 100) width = 100;
626   if (width < 0) width = 0;
627 
628   tflag = LMAPI->get_flags();
629 
630   curcol = 1;
631 
632   if (!LMAPI->user_find_list(LMAPI->get_string("lcgi-list"),
633         LMAPI->get_string("lcgi-user"), &user)) {
634      printf("<b>You are not subscribed to this list.</b>");
635      return 0;
636   }
637 
638   counter = 0;
639 
640   while(tflag) {
641      counter++;
642      tflag = tflag->next;
643   }
644 
645   flagarr = (struct listserver_flag **)malloc(sizeof(struct listserver_flag *) * counter);
646 
647   tflag = LMAPI->get_flags();
648 
649   for (i = 0; i < counter; i++) {
650      flagarr[i] = tflag;
651      tflag = tflag->next;
652   }
653 
654   qsort(flagarr,counter,sizeof(struct listserver_flag *),flag_cmp);
655 
656   printf("<table border=0");
657   if (width) {
658      printf(" width=%d%%", width);
659   }
660   printf(">\n");
661   printf(" <tr>\n");
662 
663   for(i = 0; i < counter; i++) {
664      if (!curcol) curcol = 1;
665      tflag = flagarr[i];
666      if (!LMAPI->user_hasflag(&user,tflag->name)) {
667         tflag = tflag->next;
668         continue;
669      }
670 
671      printf("  <td valign=top>\n");
672      printf("<b>%s</b>\n", tflag->name);
673      printf("  </td><td valign=top>\n");
674      printf("   %s\n", tflag->desc);
675      printf("  </td>");
676 
677      tflag = tflag->next;
678      curcol++;
679 
680      if (curcol > cols) {
681         printf(" </tr>\n<tr>\n");
682         curcol = 0;
683      }
684   }
685 
686   if (curcol != 0) {
687      while(curcol < cols) {
688         printf("  <td>&nbsp;</td><td>&nbsp;</td>\n");
689         curcol++;
690      }
691      printf(" </tr>\n");
692   }
693 
694   free(flagarr);
695 
696   printf("</table>");
697   return 1;
698 }
699