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)
646 #define NUM_CONFIGS 37
649 char sc[NUM_CONFIGS][SIZ];
651 struct ExpirePolicy *site_expirepolicy = NULL;
652 struct ExpirePolicy *mbx_expirepolicy = NULL;
655 int r; /* IPC response code */
657 /* Clear out the config buffers */
658 memset(&sc[0][0], 0, sizeof(sc));
660 /* Fetch the current config */
661 r = CtdlIPCGetSystemConfig(ipc, &resp, buf);
664 while (strlen(resp)) {
665 extract_token(buf, resp, 0, '\n');
666 remove_token(resp, 0, '\n');
667 if (a < NUM_CONFIGS) {
668 strcpy(&sc[a][0], buf);
673 if (resp) free(resp);
675 /* Fetch the expire policy (this will silently fail on old servers,
676 * resulting in "default" policy)
678 r = CtdlIPCGetMessageExpirationPolicy(ipc, 2, &site_expirepolicy, buf);
679 r = CtdlIPCGetMessageExpirationPolicy(ipc, 3, &mbx_expirepolicy, buf);
681 /* Identification parameters */
683 strprompt("Node name", &sc[0][0], 15);
684 strprompt("Fully qualified domain name", &sc[1][0], 63);
685 strprompt("Human readable node name", &sc[2][0], 20);
686 strprompt("Modem dialup number", &sc[3][0], 15);
687 strprompt("Geographic location of this system", &sc[12][0], 31);
688 strprompt("Name of system administrator", &sc[13][0], 25);
689 strprompt("Paginator prompt", &sc[10][0], 79);
691 /* Security parameters */
693 snprintf(sc[7], sizeof sc[7], "%d", (boolprompt(
694 "Require registration for new users",
696 snprintf(sc[29], sizeof sc[29], "%d", (boolprompt(
697 "Disable self-service user account creation",
699 strprompt("Initial access level for new users", &sc[6][0], 1);
700 strprompt("Access level required to create rooms", &sc[19][0], 1);
701 snprintf(sc[4], sizeof sc[4], "%d", (boolprompt(
702 "Automatically give room aide privs to a user who creates a private room",
705 snprintf(sc[8], sizeof sc[8], "%d", (boolprompt(
706 "Automatically move problem user messages to twit room",
709 strprompt("Name of twit room", &sc[9][0], ROOMNAMELEN);
710 snprintf(sc[11], sizeof sc[11], "%d", (boolprompt(
711 "Restrict Internet mail to only those with that privilege",
713 snprintf(sc[26], sizeof sc[26], "%d", (boolprompt(
714 "Allow Aides to Zap (forget) rooms",
716 snprintf(sc[30], sizeof sc[30], "%d", (boolprompt(
717 "Allow system Aides access to user mailboxes",
720 if (strlen(&sc[18][0]) > 0) logpages = 1;
722 logpages = boolprompt("Log all pages", logpages);
724 strprompt("Name of logging room", &sc[18][0], ROOMNAMELEN);
733 strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4);
734 strprompt("Maximum concurrent sessions", &sc[14][0], 4);
735 strprompt("Maximum message length", &sc[20][0], 20);
736 strprompt("Minimum number of worker threads", &sc[21][0], 3);
737 strprompt("Maximum number of worker threads", &sc[22][0], 3);
739 strprompt("POP3 server port (-1 to disable)", &sc[23][0], 5);
740 strprompt("IMAP server port (-1 to disable)", &sc[27][0], 5);
741 strprompt("SMTP server port (-1 to disable)", &sc[24][0], 5);
743 /* This logic flips the question around, because it's one of those
744 * situations where 0=yes and 1=no
748 a = boolprompt("Correct forged From: lines during authenticated SMTP",
751 snprintf(sc[25], sizeof sc[25], "%d", a);
754 if (serv_info.serv_supports_ldap) {
755 a = strlen(&sc[32][0]);
756 a = (a ? 1 : 0); /* Set only to 1 or 0 */
757 a = boolprompt("Connect this Citadel to an LDAP directory", a);
759 strprompt("Host name of LDAP server",
761 strprompt("Port number of LDAP service",
763 strprompt("Base DN", &sc[34][0], 255);
764 strprompt("Bind DN", &sc[35][0], 255);
765 strprompt("Password for bind DN", &sc[36][0], 255);
768 strcpy(&sc[32][0], "");
772 /* Expiry settings */
773 strprompt("Default user purge time (days)", &sc[16][0], 5);
774 strprompt("Default room purge time (days)", &sc[17][0], 5);
776 /* Angels and demons dancing in my head... */
778 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_mode);
779 strprompt("System default message expire policy (? for list)",
783 "1. Never automatically expire messages\n"
784 "2. Expire by message count\n"
785 "3. Expire by message age\n");
787 } while ((buf[0] < '1') || (buf[0] > '3'));
788 site_expirepolicy->expire_mode = buf[0] - '0';
790 /* ...lunatics and monsters underneath my bed */
791 if (site_expirepolicy->expire_mode == 2) {
792 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
793 strprompt("Keep how many messages online?", buf, 10);
794 site_expirepolicy->expire_value = atol(buf);
796 if (site_expirepolicy->expire_mode == 3) {
797 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
798 strprompt("Keep messages for how many days?", buf, 10);
799 site_expirepolicy->expire_value = atol(buf);
802 /* Media messiahs preying on my fears... */
804 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_mode);
805 strprompt("Mailbox default message expire policy (? for list)",
809 "0. Go with the system default\n"
810 "1. Never automatically expire messages\n"
811 "2. Expire by message count\n"
812 "3. Expire by message age\n");
814 } while ((buf[0] < '0') || (buf[0] > '3'));
815 mbx_expirepolicy->expire_mode = buf[0] - '0';
817 /* ...Pop culture prophets playing in my ears */
818 if (mbx_expirepolicy->expire_mode == 2) {
819 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
820 strprompt("Keep how many messages online?", buf, 10);
821 mbx_expirepolicy->expire_value = atol(buf);
823 if (mbx_expirepolicy->expire_mode == 3) {
824 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
825 strprompt("Keep messages for how many days?", buf, 10);
826 mbx_expirepolicy->expire_value = atol(buf);
829 strprompt("How often to run network jobs (in seconds)", &sc[28][0], 5);
830 strprompt("Hour to run purges (0-23)", &sc[31][0], 2);
833 scr_printf("Save this configuration? ");
836 for (a = 0; a < NUM_CONFIGS; a++)
837 r += 1 + strlen(sc[a]);
838 resp = (char *)calloc(1, r);
840 err_printf("Can't save config - out of memory!\n");
843 for (a = 0; a < NUM_CONFIGS; a++) {
847 r = CtdlIPCSetSystemConfig(ipc, resp, buf);
849 err_printf("%s\n", buf);
853 r = CtdlIPCSetMessageExpirationPolicy(ipc, 2, site_expirepolicy, buf);
855 err_printf("%s\n", buf);
858 r = CtdlIPCSetMessageExpirationPolicy(ipc, 3, mbx_expirepolicy, buf);
860 err_printf("%s\n", buf);
868 * support function for do_internet_configuration()
870 void get_inet_rec_type(CtdlIPC *ipc, char *buf) {
873 keyopt(" <1> localhost (Alias for this computer)\n");
874 keyopt(" <2> gateway domain (Domain for all Citadel systems)\n");
875 keyopt(" <3> smart-host (Forward all outbound mail to this host)\n");
876 keyopt(" <4> directory (Consult the Global Address Book)\n");
877 keyopt(" <5> SpamAssassin (Address of SpamAssassin server)\n");
878 keyopt(" <6> RBL (domain suffix of spam hunting RBL)\n");
879 sel = intprompt("Which one", 1, 1, 6);
881 case 1: strcpy(buf, "localhost");
883 case 2: strcpy(buf, "gatewaydomain");
885 case 3: strcpy(buf, "smarthost");
887 case 4: strcpy(buf, "directory");
889 case 5: strcpy(buf, "spamassassin");
891 case 6: strcpy(buf, "rbl");
898 * Internet mail configuration
900 void do_internet_configuration(CtdlIPC *ipc)
912 r = CtdlIPCGetSystemConfigByType(ipc, INTERNETCFG, &resp, buf);
914 while (strlen(resp)) {
915 extract_token(buf, resp, 0, '\n');
916 remove_token(resp, 0, '\n');
918 if (num_recs == 1) recs = malloc(sizeof(char *));
919 else recs = realloc(recs, (sizeof(char *)) * num_recs);
920 recs[num_recs-1] = malloc(strlen(buf) + 1);
921 strcpy(recs[num_recs-1], buf);
924 if (resp) free(resp);
929 scr_printf("### Host or domain Record type \n");
931 scr_printf("--- -------------------------------------------------- --------------------\n");
932 for (i=0; i<num_recs; ++i) {
934 scr_printf("%3d ", i+1);
935 extract(buf, recs[i], 0);
937 scr_printf("%-50s ", buf);
938 extract(buf, recs[i], 1);
939 color(BRIGHT_MAGENTA);
940 scr_printf("%-20s\n", buf);
944 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
947 newprompt("Enter host name: ",
950 if (strlen(buf) > 0) {
953 recs = malloc(sizeof(char *));
954 else recs = realloc(recs,
955 (sizeof(char *)) * num_recs);
957 get_inet_rec_type(ipc,
959 recs[num_recs-1] = strdup(buf);
963 i = intprompt("Delete which one",
967 for (j=i; j<num_recs; ++j)
972 for (i = 0; i < num_recs; i++)
973 r += 1 + strlen(recs[i]);
974 resp = (char *)calloc(1, r);
976 err_printf("Can't save config - out of memory!\n");
979 if (num_recs) for (i = 0; i < num_recs; i++) {
980 strcat(resp, recs[i]);
983 r = CtdlIPCSetSystemConfigByType(ipc, INTERNETCFG, resp, buf);
985 err_printf("%s\n", buf);
990 quitting = boolprompt(
991 "Quit without saving", 0);
996 } while (quitting == 0);
999 for (i=0; i<num_recs; ++i) free(recs[i]);
1007 * Edit network configuration for room sharing, mailing lists, etc.
1009 void network_config_management(CtdlIPC *ipc, char *entrytype, char *comment)
1011 char filename[PATH_MAX];
1012 char changefile[PATH_MAX];
1023 if (strlen(editor_paths[0]) == 0) {
1024 scr_printf("You must have an external editor configured in"
1025 " order to use this function.\n");
1029 snprintf(filename, sizeof filename, "%s.listedit", tmpnam(NULL));
1030 snprintf(changefile, sizeof changefile, "%s.listedit", tmpnam(NULL));
1032 tempfp = fopen(filename, "w");
1033 if (tempfp == NULL) {
1034 err_printf("Cannot open %s: %s\n", filename, strerror(errno));
1038 fprintf(tempfp, "# Configuration for room: %s\n", room_name);
1039 fprintf(tempfp, "# %s\n", comment);
1040 fprintf(tempfp, "# Specify one per line.\n"
1043 CtdlIPC_putline(ipc, "GNET");
1044 CtdlIPC_getline(ipc, buf);
1045 if (buf[0] == '1') {
1046 while(CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1047 extract(instr, buf, 0);
1048 if (!strcasecmp(instr, entrytype)) {
1049 extract(addr, buf, 1);
1050 fprintf(tempfp, "%s\n", addr);
1056 e_ex_code = 1; /* start with a failed exit code */
1058 sttybbs(SB_RESTORE);
1059 editor_pid = fork();
1060 cksum = file_checksum(filename);
1061 if (editor_pid == 0) {
1062 chmod(filename, 0600);
1063 putenv("WINDOW_TITLE=Network configuration");
1064 execlp(editor_paths[0], editor_paths[0], filename, NULL);
1067 if (editor_pid > 0) {
1070 b = ka_wait(&e_ex_code);
1071 } while ((b != editor_pid) && (b >= 0));
1077 if (file_checksum(filename) == cksum) {
1078 err_printf("*** Not saving changes.\n");
1082 if (e_ex_code == 0) { /* Save changes */
1083 changefp = fopen(changefile, "w");
1084 CtdlIPC_putline(ipc, "GNET");
1085 CtdlIPC_getline(ipc, buf);
1086 if (buf[0] == '1') {
1087 while(CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1088 extract(instr, buf, 0);
1089 if (strcasecmp(instr, entrytype)) {
1090 fprintf(changefp, "%s\n", buf);
1094 tempfp = fopen(filename, "r");
1095 while (fgets(buf, sizeof buf, tempfp) != NULL) {
1096 for (i=0; i<strlen(buf); ++i) {
1097 if (buf[i] == '#') buf[i] = 0;
1100 if (strlen(buf) > 0) {
1101 fprintf(changefp, "%s|%s\n", entrytype, buf);
1107 /* now write it to the server... */
1108 CtdlIPC_putline(ipc, "SNET");
1109 CtdlIPC_getline(ipc, buf);
1110 if (buf[0] == '4') {
1111 changefp = fopen(changefile, "r");
1112 if (changefp != NULL) {
1113 while (fgets(buf, sizeof buf,
1114 changefp) != NULL) {
1115 buf[strlen(buf) - 1] = 0;
1116 CtdlIPC_putline(ipc, buf);
1120 CtdlIPC_putline(ipc, "000");
1124 unlink(filename); /* Delete the temporary files */
1130 * IGnet node configuration
1132 void do_ignet_configuration(CtdlIPC *ipc) {
1142 snprintf(buf, sizeof buf, "CONF getsys|%s", IGNETCFG);
1143 CtdlIPC_putline(ipc, buf);
1144 CtdlIPC_getline(ipc, buf);
1145 if (buf[0] == '1') while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1147 if (num_recs == 1) recs = malloc(sizeof(char *));
1148 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1149 recs[num_recs-1] = malloc(SIZ);
1150 strcpy(recs[num_recs-1], buf);
1155 color(BRIGHT_WHITE);
1164 "------------------ "
1165 "-------------------------------- "
1167 for (i=0; i<num_recs; ++i) {
1169 scr_printf("%3d ", i+1);
1170 extract(buf, recs[i], 0);
1172 scr_printf("%-16s ", buf);
1173 extract(buf, recs[i], 1);
1174 color(BRIGHT_MAGENTA);
1175 scr_printf("%-18s ", buf);
1176 extract(buf, recs[i], 2);
1178 scr_printf("%-32s ", buf);
1179 extract(buf, recs[i], 3);
1180 color(BRIGHT_MAGENTA);
1181 scr_printf("%-3s\n", buf);
1185 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1190 recs = malloc(sizeof(char *));
1191 else recs = realloc(recs,
1192 (sizeof(char *)) * num_recs);
1193 newprompt("Enter node name : ", buf, 16);
1195 newprompt("Enter shared secret: ",
1196 &buf[strlen(buf)], 18);
1198 newprompt("Enter host or IP : ",
1199 &buf[strlen(buf)], 32);
1200 strcat(buf, "|504");
1201 strprompt("Enter port number : ",
1202 &buf[strlen(buf)-3], 5);
1203 recs[num_recs-1] = strdup(buf);
1206 i = intprompt("Delete which one",
1207 1, 1, num_recs) - 1;
1210 for (j=i; j<num_recs; ++j)
1211 recs[j] = recs[j+1];
1214 snprintf(buf, sizeof buf, "CONF putsys|%s", IGNETCFG);
1215 CtdlIPC_putline(ipc, buf);
1216 CtdlIPC_getline(ipc, buf);
1217 if (buf[0] == '4') {
1218 for (i=0; i<num_recs; ++i) {
1219 CtdlIPC_putline(ipc, recs[i]);
1221 CtdlIPC_putline(ipc, "000");
1224 scr_printf("%s\n", &buf[4]);
1229 quitting = boolprompt(
1230 "Quit without saving", 0);
1235 } while (quitting == 0);
1238 for (i=0; i<num_recs; ++i) free(recs[i]);
1244 * Filter list configuration
1246 void do_filterlist_configuration(CtdlIPC *ipc)
1257 snprintf(buf, sizeof buf, "CONF getsys|%s", FILTERLIST);
1258 CtdlIPC_putline(ipc, buf);
1259 CtdlIPC_getline(ipc, buf);
1260 if (buf[0] == '1') while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1262 if (num_recs == 1) recs = malloc(sizeof(char *));
1263 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1264 recs[num_recs-1] = malloc(SIZ);
1265 strcpy(recs[num_recs-1], buf);
1270 color(BRIGHT_WHITE);
1278 "---------------------------- "
1279 "---------------------------- "
1282 for (i=0; i<num_recs; ++i) {
1284 scr_printf("%3d ", i+1);
1285 extract(buf, recs[i], 0);
1287 scr_printf("%-28s ", buf);
1288 extract(buf, recs[i], 1);
1289 color(BRIGHT_MAGENTA);
1290 scr_printf("%-28s ", buf);
1291 extract(buf, recs[i], 2);
1293 scr_printf("%-16s\n", buf);
1294 extract(buf, recs[i], 3);
1298 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1303 recs = malloc(sizeof(char *));
1304 else recs = realloc(recs,
1305 (sizeof(char *)) * num_recs);
1306 newprompt("Enter user name: ", buf, 28);
1308 newprompt("Enter room name: ",
1309 &buf[strlen(buf)], 28);
1311 newprompt("Enter node name: ",
1312 &buf[strlen(buf)], 16);
1314 recs[num_recs-1] = strdup(buf);
1317 i = intprompt("Delete which one",
1318 1, 1, num_recs) - 1;
1321 for (j=i; j<num_recs; ++j)
1322 recs[j] = recs[j+1];
1325 snprintf(buf, sizeof buf, "CONF putsys|%s", FILTERLIST);
1326 CtdlIPC_putline(ipc, buf);
1327 CtdlIPC_getline(ipc, buf);
1328 if (buf[0] == '4') {
1329 for (i=0; i<num_recs; ++i) {
1330 CtdlIPC_putline(ipc, recs[i]);
1332 CtdlIPC_putline(ipc, "000");
1335 scr_printf("%s\n", &buf[4]);
1340 quitting = boolprompt(
1341 "Quit without saving", 0);
1346 } while (quitting == 0);
1349 for (i=0; i<num_recs; ++i) free(recs[i]);