3 * More client-side support functions.
4 * Unlike routines.c, some of these DO use global variables.
11 #include <sys/types.h>
19 #if TIME_WITH_SYS_TIME
20 # include <sys/time.h>
24 # include <sys/time.h>
35 #include "citadel_ipc.h"
36 #include "citadel_decls.h"
37 #include "routines2.h"
47 /* work around solaris include files */
53 extern char tempdir[];
54 extern char *axdefs[7];
55 extern long highest_msg_read;
56 extern long maxmsgnum;
57 extern unsigned room_flags;
58 extern int screenwidth;
62 int eopen(char *name, int mode)
65 ret = open(name, mode);
67 err_printf("Cannot open file '%s', mode=%d, errno=%d\n",
76 int room_prompt(unsigned int qrflags)
77 { /* return proper room prompt character */
80 if (qrflags & QR_DIRECTORY)
82 if ((a == ']') && (qrflags & QR_NETWORK))
84 if ((a == '>') && (qrflags & QR_NETWORK))
89 void entregis(CtdlIPC *ipc)
90 { /* register with name and address */
100 char tmpcountry[SIZ];
106 int r; /* IPC response code */
111 strcpy(tmpstate, "");
113 strcpy(tmpphone, "");
114 strcpy(tmpemail, "");
115 strcpy(tmpcountry, "");
117 r = CtdlIPCGetUserRegistration(ipc, NULL, ®, buf);
121 while (reg && strlen(reg) > 0) {
123 extract_token(buf, reg, 0, '\n');
124 remove_token(reg, 0, '\n');
127 strcpy(tmpname, buf);
129 strcpy(tmpaddr, buf);
131 strcpy(tmpcity, buf);
133 strcpy(tmpstate, buf);
137 strcpy(tmpphone, buf);
139 strcpy(tmpemail, buf);
141 strcpy(tmpcountry, buf);
145 strprompt("REAL name", tmpname, 29);
146 strprompt("Address", tmpaddr, 24);
147 strprompt("City/town", tmpcity, 14);
148 strprompt("State/province", tmpstate, 2);
149 strprompt("ZIP/Postal Code", tmpzip, 10);
150 strprompt("Country", tmpcountry, 31);
151 strprompt("Telephone number", tmpphone, 14);
155 strcpy(holdemail, tmpemail);
156 strprompt("Email address", tmpemail, 31);
157 r = CtdlIPCDirectoryLookup(ipc, tmpemail, buf);
159 extract_token(diruser, buf, 0, '@');
160 extract_token(dirnode, buf, 1, '@');
163 if ((strcasecmp(diruser, fullname))
164 || (strcasecmp(dirnode, serv_info.serv_nodename))) {
166 "\nYou can't use %s as your address.\n",
169 "It is already in use by %s @ %s.\n",
172 strcpy(tmpemail, holdemail);
177 /* now send the registration info back to the server */
178 reg = (char *)realloc(reg, 4096); /* Overkill? */
180 sprintf(reg, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
181 tmpname, tmpaddr, tmpcity, tmpstate,
182 tmpzip, tmpphone, tmpemail, tmpcountry);
183 r = CtdlIPCSetRegistration(ipc, reg, buf);
185 scr_printf("%s\n", buf);
191 void updatels(CtdlIPC *ipc)
192 { /* make all messages old in current room */
194 int r; /* IPC response code */
196 if (rc_alt_semantics) {
197 if (maxmsgnum == 0 && highest_msg_read == 0) {
200 r = CtdlIPCSetLastRead(ipc, (maxmsgnum > highest_msg_read) ?
201 maxmsgnum : highest_msg_read, buf);
203 r = CtdlIPCSetLastRead(ipc, (maxmsgnum > highest_msg_read) ?
204 maxmsgnum : highest_msg_read, buf);
205 /* r = CtdlIPCSetLastRead(ipc, maxmsgnum, buf); */
206 /* This is a quick-and-dirty fix to all msgs becoming new in Mail>.
207 * It will need to be rethought when messages.c is rewritten.
211 scr_printf("%s\n", buf);
215 * only make messages old in this room that have been read
217 void updatelsa(CtdlIPC *ipc)
220 int r; /* IPC response code */
222 r = CtdlIPCSetLastRead(ipc, highest_msg_read, buf);
224 scr_printf("%s\n", &buf[4]);
229 * client-based uploads (for users with their own clientware)
231 void cli_upload(CtdlIPC *ipc)
237 int r; /* IPC response code */
241 if ((room_flags & QR_UPLOAD) == 0) {
242 scr_printf("*** You cannot upload to this room.\n");
245 newprompt("File to be uploaded: ", flnm, 55);
246 fd = open(flnm, O_RDONLY);
248 scr_printf("Cannot open '%s': %s\n", flnm, strerror(errno));
251 scr_printf("Enter a description of this file:\n");
252 newprompt(": ", desc, 75);
254 /* Keep generating filenames in hope of finding a unique one */
257 /* basename of filename */
259 if (haschar(tbuf, '/'))
260 extract_token(tbuf, flnm,
261 num_tokens(tbuf, '/') - 1,
264 /* filename.1, filename.2, etc */
266 sprintf(&tbuf[strlen(tbuf)], ".%d", a);
269 r = CtdlIPCFileUpload(ipc, tbuf, desc, flnm, progress, buf);
270 if (r / 100 == 5 || r < 0)
271 scr_printf("%s\n", buf);
276 if (a > 0) scr_printf("Saved as '%s'\n", tbuf);
281 * Function used for various image upload commands
283 void cli_image_upload(CtdlIPC *ipc, char *keyname)
289 /* Can we upload this image? */
290 r = CtdlIPCImageUpload(ipc, 0, NULL, keyname, NULL, buf);
292 err_printf("%s\n", buf);
295 newprompt("Image file to be uploaded: ", flnm, 55);
296 r = CtdlIPCImageUpload(ipc, 1, flnm, keyname, progress, buf);
298 err_printf("%s\n", buf);
300 err_printf("Cannot upload '%s': %s\n", flnm, strerror(errno));
302 /* else upload succeeded */
307 * protocol-based uploads (Xmodem, Ymodem, Zmodem)
309 void upload(CtdlIPC *ipc, int c)
310 { /* c = upload mode */
320 if ((room_flags & QR_UPLOAD) == 0) {
321 scr_printf("*** You cannot upload to this room.\n");
324 /* we don't need a filename when receiving batch y/z modem */
325 if ((c == 2) || (c == 3))
328 newprompt("Enter filename: ", flnm, 15);
330 for (a = 0; a < strlen(flnm); ++a)
331 if ((flnm[a] == '/') || (flnm[a] == '\\') || (flnm[a] == '>')
332 || (flnm[a] == '?') || (flnm[a] == '*')
333 || (flnm[a] == ';') || (flnm[a] == '&'))
336 /* create a temporary directory... */
337 if (mkdir(tempdir, 0700) != 0) {
338 scr_printf("*** Could not create temporary directory %s: %s\n",
339 tempdir, strerror(errno));
342 /* now do the transfer ... in a separate process */
349 scr_printf("Receiving %s - press Ctrl-D to end.\n", flnm);
350 fp = fopen(flnm, "w");
366 execlp("rx", "rx", flnm, NULL);
371 execlp("rb", "rb", NULL);
376 execlp("rz", "rz", NULL);
382 } while ((b != xfer_pid) && (b != (-1)));
387 scr_printf("\r*** Transfer unsuccessful.\n");
391 scr_printf("\r*** Transfer successful.\n");
392 snprintf(buf, sizeof buf, "cd %s; ls", tempdir);
393 lsfp = popen(buf, "r");
395 while (fgets(flnm, sizeof flnm, lsfp) != NULL) {
396 flnm[strlen(flnm) - 1] = 0; /* chop newline */
397 snprintf(buf, sizeof buf,
398 "Enter a short description of '%s':\n: ",
400 newprompt(buf, desc, 150);
401 snprintf(buf, sizeof buf, "%s/%s", tempdir, flnm);
402 r = CtdlIPCFileUpload(ipc, flnm, desc, buf, progress, tbuf);
403 scr_printf("%s\n", tbuf);
411 * validate a user (returns 0 for successful validation, nonzero if quitting)
413 int val_user(CtdlIPC *ipc, char *user, int do_validate)
421 int r; /* IPC response code */
424 r = CtdlIPCGetUserRegistration(ipc, user, &resp, cmd);
428 extract_token(buf, resp, 0, '\n');
429 remove_token(resp, 0, '\n');
432 scr_printf("User #%s - %s ", buf, cmd);
434 scr_printf("PW: %s\n", buf);
436 scr_printf("%s\n", buf);
438 scr_printf("%s\n", buf);
440 scr_printf("%s, ", buf);
442 scr_printf("%s ", buf);
444 scr_printf("%s\n", buf);
446 scr_printf("%s\n", buf);
450 scr_printf("%s\n", buf);
452 scr_printf("%s\n", buf);
453 } while (strlen(resp));
454 scr_printf("Current access level: %d (%s)\n", ax, axdefs[ax]);
456 scr_printf("%s\n%s\n", user, &cmd[4]);
458 if (resp) free(resp);
461 /* now set the access level */
463 sprintf(answer, "%d", ax);
464 strprompt("New access level (? for help, q to quit)",
466 if ((answer[0] >= '0') && (answer[0] <= '6')) {
468 r = CtdlIPCValidateUser(ipc, user, ax, cmd);
470 scr_printf("%s\n\n", cmd);
473 if (tolower(answer[0]) == 'q') {
474 scr_printf("*** Aborted.\n\n");
477 if (answer[0] == '?') {
478 scr_printf("Available access levels:\n");
479 for (a=0; a<7; ++a) {
480 scr_printf("%d - %s\n",
490 void validate(CtdlIPC *ipc)
491 { /* validate new users */
495 int r; /* IPC response code */
498 r = CtdlIPCNextUnvalidatedUser(ipc, cmd);
502 scr_printf("%s\n", cmd);
504 extract(buf, cmd, 0);
505 if (val_user(ipc, buf, 1) != 0) finished = 1;
507 } while (finished == 0);
517 signal(SIGINT, SIG_DFL);
518 signal(SIGQUIT, SIG_DFL);
519 execlp(getenv("SHELL"), getenv("SHELL"), NULL);
520 err_printf("Could not open a shell: %s\n", strerror(errno));
525 } while ((a != b) && (a != (-1)));
531 * <.A>ide <F>ile <D>elete command
533 void deletefile(CtdlIPC *ipc)
538 newprompt("Filename: ", filename, 31);
539 if (strlen(filename) == 0)
541 CtdlIPCDeleteFile(ipc, filename, buf);
542 err_printf("%s\n", buf);
546 * <.A>ide <F>ile <S>end command
548 void netsendfile(CtdlIPC *ipc)
550 char filename[32], destsys[20], buf[SIZ];
552 newprompt("Filename: ", filename, 31);
553 if (strlen(filename) == 0)
555 newprompt("System to send to: ", destsys, 19);
556 CtdlIPCNetSendFile(ipc, filename, destsys, buf);
557 err_printf("%s\n", buf);
562 * <.A>ide <F>ile <M>ove command
564 void movefile(CtdlIPC *ipc)
567 char newroom[ROOMNAMELEN];
570 newprompt("Filename: ", filename, 63);
571 if (strlen(filename) == 0)
573 newprompt("Enter target room: ", newroom, ROOMNAMELEN - 1);
574 CtdlIPCMoveFile(ipc, filename, newroom, buf);
575 err_printf("%s\n", buf);
580 * list of users who have filled out a bio
582 void list_bio(CtdlIPC *ipc)
587 int r; /* IPC response code */
589 r = CtdlIPCListUsersWithBios(ipc, &resp, buf);
591 pprintf("%s\n", buf);
594 while (strlen(resp)) {
595 extract_token(buf, resp, 0, '\n');
596 remove_token(resp, 0, '\n');
597 if ((pos + strlen(buf) + 5) > screenwidth) {
601 pprintf("%s, ", buf);
602 pos = pos + strlen(buf) + 2;
604 pprintf("%c%c \n\n", 8, 8);
605 if (resp) free(resp);
612 void read_bio(CtdlIPC *ipc)
617 int r; /* IPC response code */
620 newprompt("Read bio for who ('?' for list) : ", who, 25);
622 if (!strcmp(who, "?"))
624 } while (!strcmp(who, "?"));
626 r = CtdlIPCGetBio(ipc, who, &resp, buf);
628 pprintf("%s\n", buf);
631 while (strlen(resp)) {
632 extract_token(buf, resp, 0, '\n');
633 remove_token(resp, 0, '\n');
634 pprintf("%s\n", buf);
636 if (resp) free(resp);
641 * General system configuration command
643 void do_system_configuration(CtdlIPC *ipc)
648 struct ExpirePolicy *site_expirepolicy = NULL;
649 struct ExpirePolicy *mbx_expirepolicy = NULL;
652 int r; /* IPC response code */
654 /* Clear out the config buffers */
655 memset(&sc[0][0], 0, sizeof(sc));
657 /* Fetch the current config */
658 r = CtdlIPCGetSystemConfig(ipc, &resp, buf);
661 while (strlen(resp)) {
662 extract_token(buf, resp, 0, '\n');
663 remove_token(resp, 0, '\n');
665 strcpy(&sc[a][0], buf);
670 if (resp) free(resp);
672 /* Fetch the expire policy (this will silently fail on old servers,
673 * resulting in "default" policy)
675 r = CtdlIPCGetMessageExpirationPolicy(ipc, 2, &site_expirepolicy, buf);
676 r = CtdlIPCGetMessageExpirationPolicy(ipc, 3, &mbx_expirepolicy, buf);
678 /* Identification parameters */
680 strprompt("Node name", &sc[0][0], 15);
681 strprompt("Fully qualified domain name", &sc[1][0], 63);
682 strprompt("Human readable node name", &sc[2][0], 20);
683 strprompt("Modem dialup number", &sc[3][0], 15);
684 strprompt("Geographic location of this system", &sc[12][0], 31);
685 strprompt("Name of system administrator", &sc[13][0], 25);
686 strprompt("Paginator prompt", &sc[10][0], 79);
688 /* Security parameters */
690 snprintf(sc[7], sizeof sc[7], "%d", (boolprompt(
691 "Require registration for new users",
693 snprintf(sc[29], sizeof sc[29], "%d", (boolprompt(
694 "Disable self-service user account creation",
696 strprompt("Initial access level for new users", &sc[6][0], 1);
697 strprompt("Access level required to create rooms", &sc[19][0], 1);
698 snprintf(sc[4], sizeof sc[4], "%d", (boolprompt(
699 "Automatically give room aide privs to a user who creates a private room",
702 snprintf(sc[8], sizeof sc[8], "%d", (boolprompt(
703 "Automatically move problem user messages to twit room",
706 strprompt("Name of twit room", &sc[9][0], ROOMNAMELEN);
707 snprintf(sc[11], sizeof sc[11], "%d", (boolprompt(
708 "Restrict Internet mail to only those with that privilege",
710 snprintf(sc[26], sizeof sc[26], "%d", (boolprompt(
711 "Allow Aides to Zap (forget) rooms",
713 snprintf(sc[30], sizeof sc[30], "%d", (boolprompt(
714 "Allow system Aides access to user mailboxes",
717 if (strlen(&sc[18][0]) > 0) logpages = 1;
719 logpages = boolprompt("Log all pages", logpages);
721 strprompt("Name of logging room", &sc[18][0], ROOMNAMELEN);
730 strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4);
731 strprompt("Maximum concurrent sessions", &sc[14][0], 4);
732 strprompt("Maximum message length", &sc[20][0], 20);
733 strprompt("Minimum number of worker threads", &sc[21][0], 3);
734 strprompt("Maximum number of worker threads", &sc[22][0], 3);
736 strprompt("POP3 server port (-1 to disable)", &sc[23][0], 5);
737 strprompt("IMAP server port (-1 to disable)", &sc[27][0], 5);
738 strprompt("SMTP server port (-1 to disable)", &sc[24][0], 5);
740 /* This logic flips the question around, because it's one of those
741 * situations where 0=yes and 1=no
745 a = boolprompt("Correct forged From: lines during authenticated SMTP",
748 snprintf(sc[25], sizeof sc[25], "%d", a);
750 /* Expiry settings */
751 strprompt("Default user purge time (days)", &sc[16][0], 5);
752 strprompt("Default room purge time (days)", &sc[17][0], 5);
754 /* Angels and demons dancing in my head... */
756 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_mode);
757 strprompt("System default message expire policy (? for list)",
761 "1. Never automatically expire messages\n"
762 "2. Expire by message count\n"
763 "3. Expire by message age\n");
765 } while ((buf[0] < '1') || (buf[0] > '3'));
766 site_expirepolicy->expire_mode = buf[0] - '0';
768 /* ...lunatics and monsters underneath my bed */
769 if (site_expirepolicy->expire_mode == 2) {
770 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
771 strprompt("Keep how many messages online?", buf, 10);
772 site_expirepolicy->expire_value = atol(buf);
774 if (site_expirepolicy->expire_mode == 3) {
775 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
776 strprompt("Keep messages for how many days?", buf, 10);
777 site_expirepolicy->expire_value = atol(buf);
780 /* Media messiahs preying on my fears... */
782 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_mode);
783 strprompt("Mailbox default message expire policy (? for list)",
787 "0. Go with the system default\n"
788 "1. Never automatically expire messages\n"
789 "2. Expire by message count\n"
790 "3. Expire by message age\n");
792 } while ((buf[0] < '0') || (buf[0] > '3'));
793 mbx_expirepolicy->expire_mode = buf[0] - '0';
795 /* ...Pop culture prophets playing in my ears */
796 if (mbx_expirepolicy->expire_mode == 2) {
797 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
798 strprompt("Keep how many messages online?", buf, 10);
799 mbx_expirepolicy->expire_value = atol(buf);
801 if (mbx_expirepolicy->expire_mode == 3) {
802 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
803 strprompt("Keep messages for how many days?", buf, 10);
804 mbx_expirepolicy->expire_value = atol(buf);
807 strprompt("How often to run network jobs (in seconds)", &sc[28][0], 5);
808 strprompt("Hour to run purges (0-23)", &sc[31][0], 2);
811 scr_printf("Save this configuration? ");
814 for (a = 0; a < 32; a++)
815 r += 1 + strlen(sc[a]);
816 resp = (char *)calloc(1, r);
818 err_printf("Can't save config - out of memory!\n");
821 for (a = 0; a < 32; a++) {
825 r = CtdlIPCSetSystemConfig(ipc, resp, buf);
827 err_printf("%s\n", buf);
831 r = CtdlIPCSetMessageExpirationPolicy(ipc, 2, site_expirepolicy, buf);
833 err_printf("%s\n", buf);
836 r = CtdlIPCSetMessageExpirationPolicy(ipc, 3, mbx_expirepolicy, buf);
838 err_printf("%s\n", buf);
846 * support function for do_internet_configuration()
848 void get_inet_rec_type(CtdlIPC *ipc, char *buf) {
851 keyopt(" <1> localhost (Alias for this computer)\n");
852 keyopt(" <2> gateway domain (Domain for all Citadel systems)\n");
853 keyopt(" <3> smart-host (Forward all outbound mail to this host)\n");
854 keyopt(" <4> directory (Consult the Global Address Book)\n");
855 keyopt(" <5> SpamAssassin (Address of SpamAssassin server)\n");
856 keyopt(" <6> RBL (domain suffix of spam hunting RBL)\n");
857 sel = intprompt("Which one", 1, 1, 6);
859 case 1: strcpy(buf, "localhost");
861 case 2: strcpy(buf, "gatewaydomain");
863 case 3: strcpy(buf, "smarthost");
865 case 4: strcpy(buf, "directory");
867 case 5: strcpy(buf, "spamassassin");
869 case 6: strcpy(buf, "rbl");
876 * Internet mail configuration
878 void do_internet_configuration(CtdlIPC *ipc)
890 r = CtdlIPCGetSystemConfigByType(ipc, INTERNETCFG, &resp, buf);
892 while (strlen(resp)) {
893 extract_token(buf, resp, 0, '\n');
894 remove_token(resp, 0, '\n');
896 if (num_recs == 1) recs = malloc(sizeof(char *));
897 else recs = realloc(recs, (sizeof(char *)) * num_recs);
898 recs[num_recs-1] = malloc(strlen(buf) + 1);
899 strcpy(recs[num_recs-1], buf);
902 if (resp) free(resp);
907 scr_printf("### Host or domain Record type \n");
909 scr_printf("--- -------------------------------------------------- --------------------\n");
910 for (i=0; i<num_recs; ++i) {
912 scr_printf("%3d ", i+1);
913 extract(buf, recs[i], 0);
915 scr_printf("%-50s ", buf);
916 extract(buf, recs[i], 1);
917 color(BRIGHT_MAGENTA);
918 scr_printf("%-20s\n", buf);
922 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
925 newprompt("Enter host name: ",
928 if (strlen(buf) > 0) {
931 recs = malloc(sizeof(char *));
932 else recs = realloc(recs,
933 (sizeof(char *)) * num_recs);
935 get_inet_rec_type(ipc,
937 recs[num_recs-1] = strdup(buf);
941 i = intprompt("Delete which one",
945 for (j=i; j<num_recs; ++j)
950 for (i = 0; i < num_recs; i++)
951 r += 1 + strlen(recs[i]);
952 resp = (char *)calloc(1, r);
954 err_printf("Can't save config - out of memory!\n");
957 if (num_recs) for (i = 0; i < num_recs; i++) {
958 strcat(resp, recs[i]);
961 r = CtdlIPCSetSystemConfigByType(ipc, INTERNETCFG, resp, buf);
963 err_printf("%s\n", buf);
968 quitting = boolprompt(
969 "Quit without saving", 0);
974 } while (quitting == 0);
977 for (i=0; i<num_recs; ++i) free(recs[i]);
985 * Edit network configuration for room sharing, mailing lists, etc.
987 void network_config_management(CtdlIPC *ipc, char *entrytype, char *comment)
989 char filename[PATH_MAX];
990 char changefile[PATH_MAX];
1001 if (strlen(editor_paths[0]) == 0) {
1002 scr_printf("You must have an external editor configured in"
1003 " order to use this function.\n");
1007 snprintf(filename, sizeof filename, "%s.listedit", tmpnam(NULL));
1008 snprintf(changefile, sizeof changefile, "%s.listedit", tmpnam(NULL));
1010 tempfp = fopen(filename, "w");
1011 if (tempfp == NULL) {
1012 err_printf("Cannot open %s: %s\n", filename, strerror(errno));
1016 fprintf(tempfp, "# Configuration for room: %s\n", room_name);
1017 fprintf(tempfp, "# %s\n", comment);
1018 fprintf(tempfp, "# Specify one per line.\n"
1021 CtdlIPC_putline(ipc, "GNET");
1022 CtdlIPC_getline(ipc, buf);
1023 if (buf[0] == '1') {
1024 while(CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1025 extract(instr, buf, 0);
1026 if (!strcasecmp(instr, entrytype)) {
1027 extract(addr, buf, 1);
1028 fprintf(tempfp, "%s\n", addr);
1034 e_ex_code = 1; /* start with a failed exit code */
1036 sttybbs(SB_RESTORE);
1037 editor_pid = fork();
1038 cksum = file_checksum(filename);
1039 if (editor_pid == 0) {
1040 chmod(filename, 0600);
1041 putenv("WINDOW_TITLE=Network configuration");
1042 execlp(editor_paths[0], editor_paths[0], filename, NULL);
1045 if (editor_pid > 0) {
1048 b = ka_wait(&e_ex_code);
1049 } while ((b != editor_pid) && (b >= 0));
1055 if (file_checksum(filename) == cksum) {
1056 err_printf("*** Not saving changes.\n");
1060 if (e_ex_code == 0) { /* Save changes */
1061 changefp = fopen(changefile, "w");
1062 CtdlIPC_putline(ipc, "GNET");
1063 CtdlIPC_getline(ipc, buf);
1064 if (buf[0] == '1') {
1065 while(CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1066 extract(instr, buf, 0);
1067 if (strcasecmp(instr, entrytype)) {
1068 fprintf(changefp, "%s\n", buf);
1072 tempfp = fopen(filename, "r");
1073 while (fgets(buf, sizeof buf, tempfp) != NULL) {
1074 for (i=0; i<strlen(buf); ++i) {
1075 if (buf[i] == '#') buf[i] = 0;
1078 if (strlen(buf) > 0) {
1079 fprintf(changefp, "%s|%s\n", entrytype, buf);
1085 /* now write it to the server... */
1086 CtdlIPC_putline(ipc, "SNET");
1087 CtdlIPC_getline(ipc, buf);
1088 if (buf[0] == '4') {
1089 changefp = fopen(changefile, "r");
1090 if (changefp != NULL) {
1091 while (fgets(buf, sizeof buf,
1092 changefp) != NULL) {
1093 buf[strlen(buf) - 1] = 0;
1094 CtdlIPC_putline(ipc, buf);
1098 CtdlIPC_putline(ipc, "000");
1102 unlink(filename); /* Delete the temporary files */
1108 * IGnet node configuration
1110 void do_ignet_configuration(CtdlIPC *ipc) {
1120 snprintf(buf, sizeof buf, "CONF getsys|%s", IGNETCFG);
1121 CtdlIPC_putline(ipc, buf);
1122 CtdlIPC_getline(ipc, buf);
1123 if (buf[0] == '1') while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1125 if (num_recs == 1) recs = malloc(sizeof(char *));
1126 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1127 recs[num_recs-1] = malloc(SIZ);
1128 strcpy(recs[num_recs-1], buf);
1133 color(BRIGHT_WHITE);
1142 "------------------ "
1143 "-------------------------------- "
1145 for (i=0; i<num_recs; ++i) {
1147 scr_printf("%3d ", i+1);
1148 extract(buf, recs[i], 0);
1150 scr_printf("%-16s ", buf);
1151 extract(buf, recs[i], 1);
1152 color(BRIGHT_MAGENTA);
1153 scr_printf("%-18s ", buf);
1154 extract(buf, recs[i], 2);
1156 scr_printf("%-32s ", buf);
1157 extract(buf, recs[i], 3);
1158 color(BRIGHT_MAGENTA);
1159 scr_printf("%-3s\n", buf);
1163 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1168 recs = malloc(sizeof(char *));
1169 else recs = realloc(recs,
1170 (sizeof(char *)) * num_recs);
1171 newprompt("Enter node name : ", buf, 16);
1173 newprompt("Enter shared secret: ",
1174 &buf[strlen(buf)], 18);
1176 newprompt("Enter host or IP : ",
1177 &buf[strlen(buf)], 32);
1178 strcat(buf, "|504");
1179 strprompt("Enter port number : ",
1180 &buf[strlen(buf)-3], 5);
1181 recs[num_recs-1] = strdup(buf);
1184 i = intprompt("Delete which one",
1185 1, 1, num_recs) - 1;
1188 for (j=i; j<num_recs; ++j)
1189 recs[j] = recs[j+1];
1192 snprintf(buf, sizeof buf, "CONF putsys|%s", IGNETCFG);
1193 CtdlIPC_putline(ipc, buf);
1194 CtdlIPC_getline(ipc, buf);
1195 if (buf[0] == '4') {
1196 for (i=0; i<num_recs; ++i) {
1197 CtdlIPC_putline(ipc, recs[i]);
1199 CtdlIPC_putline(ipc, "000");
1202 scr_printf("%s\n", &buf[4]);
1207 quitting = boolprompt(
1208 "Quit without saving", 0);
1213 } while (quitting == 0);
1216 for (i=0; i<num_recs; ++i) free(recs[i]);
1222 * Filter list configuration
1224 void do_filterlist_configuration(CtdlIPC *ipc)
1235 snprintf(buf, sizeof buf, "CONF getsys|%s", FILTERLIST);
1236 CtdlIPC_putline(ipc, buf);
1237 CtdlIPC_getline(ipc, buf);
1238 if (buf[0] == '1') while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1240 if (num_recs == 1) recs = malloc(sizeof(char *));
1241 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1242 recs[num_recs-1] = malloc(SIZ);
1243 strcpy(recs[num_recs-1], buf);
1248 color(BRIGHT_WHITE);
1256 "---------------------------- "
1257 "---------------------------- "
1260 for (i=0; i<num_recs; ++i) {
1262 scr_printf("%3d ", i+1);
1263 extract(buf, recs[i], 0);
1265 scr_printf("%-28s ", buf);
1266 extract(buf, recs[i], 1);
1267 color(BRIGHT_MAGENTA);
1268 scr_printf("%-28s ", buf);
1269 extract(buf, recs[i], 2);
1271 scr_printf("%-16s\n", buf);
1272 extract(buf, recs[i], 3);
1276 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1281 recs = malloc(sizeof(char *));
1282 else recs = realloc(recs,
1283 (sizeof(char *)) * num_recs);
1284 newprompt("Enter user name: ", buf, 28);
1286 newprompt("Enter room name: ",
1287 &buf[strlen(buf)], 28);
1289 newprompt("Enter node name: ",
1290 &buf[strlen(buf)], 16);
1292 recs[num_recs-1] = strdup(buf);
1295 i = intprompt("Delete which one",
1296 1, 1, num_recs) - 1;
1299 for (j=i; j<num_recs; ++j)
1300 recs[j] = recs[j+1];
1303 snprintf(buf, sizeof buf, "CONF putsys|%s", FILTERLIST);
1304 CtdlIPC_putline(ipc, buf);
1305 CtdlIPC_getline(ipc, buf);
1306 if (buf[0] == '4') {
1307 for (i=0; i<num_recs; ++i) {
1308 CtdlIPC_putline(ipc, recs[i]);
1310 CtdlIPC_putline(ipc, "000");
1313 scr_printf("%s\n", &buf[4]);
1318 quitting = boolprompt(
1319 "Quit without saving", 0);
1324 } while (quitting == 0);
1327 for (i=0; i<num_recs; ++i) free(recs[i]);