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, ipc->ServInfo.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);
518 signal(SIGINT, SIG_DFL);
519 signal(SIGQUIT, SIG_DFL);
520 execlp(getenv("SHELL"), getenv("SHELL"), NULL);
521 err_printf("Could not open a shell: %s\n", strerror(errno));
526 } while ((a != b) && (a != (-1)));
532 * <.A>ide <F>ile <D>elete command
534 void deletefile(CtdlIPC *ipc)
539 newprompt("Filename: ", filename, 31);
540 if (strlen(filename) == 0)
542 CtdlIPCDeleteFile(ipc, filename, buf);
543 err_printf("%s\n", buf);
547 * <.A>ide <F>ile <S>end command
549 void netsendfile(CtdlIPC *ipc)
551 char filename[32], destsys[20], buf[SIZ];
553 newprompt("Filename: ", filename, 31);
554 if (strlen(filename) == 0)
556 newprompt("System to send to: ", destsys, 19);
557 CtdlIPCNetSendFile(ipc, filename, destsys, buf);
558 err_printf("%s\n", buf);
563 * <.A>ide <F>ile <M>ove command
565 void movefile(CtdlIPC *ipc)
568 char newroom[ROOMNAMELEN];
571 newprompt("Filename: ", filename, 63);
572 if (strlen(filename) == 0)
574 newprompt("Enter target room: ", newroom, ROOMNAMELEN - 1);
575 CtdlIPCMoveFile(ipc, filename, newroom, buf);
576 err_printf("%s\n", buf);
581 * list of users who have filled out a bio
583 void list_bio(CtdlIPC *ipc)
588 int r; /* IPC response code */
590 r = CtdlIPCListUsersWithBios(ipc, &resp, buf);
592 pprintf("%s\n", buf);
595 while (strlen(resp)) {
596 extract_token(buf, resp, 0, '\n');
597 remove_token(resp, 0, '\n');
598 if ((pos + strlen(buf) + 5) > screenwidth) {
602 pprintf("%s, ", buf);
603 pos = pos + strlen(buf) + 2;
605 pprintf("%c%c \n\n", 8, 8);
606 if (resp) free(resp);
613 void read_bio(CtdlIPC *ipc)
618 int r; /* IPC response code */
621 newprompt("Read bio for who ('?' for list) : ", who, 25);
623 if (!strcmp(who, "?"))
625 } while (!strcmp(who, "?"));
627 r = CtdlIPCGetBio(ipc, who, &resp, buf);
629 pprintf("%s\n", buf);
632 while (strlen(resp)) {
633 extract_token(buf, resp, 0, '\n');
634 remove_token(resp, 0, '\n');
635 pprintf("%s\n", buf);
637 if (resp) free(resp);
642 * General system configuration command
644 void do_system_configuration(CtdlIPC *ipc)
647 #define NUM_CONFIGS 37
650 char sc[NUM_CONFIGS][SIZ];
652 struct ExpirePolicy *site_expirepolicy = NULL;
653 struct ExpirePolicy *mbx_expirepolicy = NULL;
656 int r; /* IPC response code */
658 /* Clear out the config buffers */
659 memset(&sc[0][0], 0, sizeof(sc));
661 /* Fetch the current config */
662 r = CtdlIPCGetSystemConfig(ipc, &resp, buf);
665 while (strlen(resp)) {
666 extract_token(buf, resp, 0, '\n');
667 remove_token(resp, 0, '\n');
668 if (a < NUM_CONFIGS) {
669 strcpy(&sc[a][0], buf);
674 if (resp) free(resp);
676 /* Fetch the expire policy (this will silently fail on old servers,
677 * resulting in "default" policy)
679 r = CtdlIPCGetMessageExpirationPolicy(ipc, 2, &site_expirepolicy, buf);
680 r = CtdlIPCGetMessageExpirationPolicy(ipc, 3, &mbx_expirepolicy, buf);
682 /* Identification parameters */
684 strprompt("Node name", &sc[0][0], 15);
685 strprompt("Fully qualified domain name", &sc[1][0], 63);
686 strprompt("Human readable node name", &sc[2][0], 20);
687 strprompt("Modem dialup number", &sc[3][0], 15);
688 strprompt("Geographic location of this system", &sc[12][0], 31);
689 strprompt("Name of system administrator", &sc[13][0], 25);
690 strprompt("Paginator prompt", &sc[10][0], 79);
692 /* Security parameters */
694 snprintf(sc[7], sizeof sc[7], "%d", (boolprompt(
695 "Require registration for new users",
697 snprintf(sc[29], sizeof sc[29], "%d", (boolprompt(
698 "Disable self-service user account creation",
700 strprompt("Initial access level for new users", &sc[6][0], 1);
701 strprompt("Access level required to create rooms", &sc[19][0], 1);
702 snprintf(sc[4], sizeof sc[4], "%d", (boolprompt(
703 "Automatically give room aide privs to a user who creates a private room",
706 snprintf(sc[8], sizeof sc[8], "%d", (boolprompt(
707 "Automatically move problem user messages to twit room",
710 strprompt("Name of twit room", &sc[9][0], ROOMNAMELEN);
711 snprintf(sc[11], sizeof sc[11], "%d", (boolprompt(
712 "Restrict Internet mail to only those with that privilege",
714 snprintf(sc[26], sizeof sc[26], "%d", (boolprompt(
715 "Allow Aides to Zap (forget) rooms",
717 snprintf(sc[30], sizeof sc[30], "%d", (boolprompt(
718 "Allow system Aides access to user mailboxes",
721 if (strlen(&sc[18][0]) > 0) logpages = 1;
723 logpages = boolprompt("Log all pages", logpages);
725 strprompt("Name of logging room", &sc[18][0], ROOMNAMELEN);
734 strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4);
735 strprompt("Maximum concurrent sessions", &sc[14][0], 4);
736 strprompt("Maximum message length", &sc[20][0], 20);
737 strprompt("Minimum number of worker threads", &sc[21][0], 3);
738 strprompt("Maximum number of worker threads", &sc[22][0], 3);
740 strprompt("POP3 server port (-1 to disable)", &sc[23][0], 5);
741 strprompt("IMAP server port (-1 to disable)", &sc[27][0], 5);
742 strprompt("SMTP server port (-1 to disable)", &sc[24][0], 5);
744 /* This logic flips the question around, because it's one of those
745 * situations where 0=yes and 1=no
749 a = boolprompt("Correct forged From: lines during authenticated SMTP",
752 snprintf(sc[25], sizeof sc[25], "%d", a);
755 if (ipc->ServInfo.supports_ldap) {
756 a = strlen(&sc[32][0]);
757 a = (a ? 1 : 0); /* Set only to 1 or 0 */
758 a = boolprompt("Connect this Citadel to an LDAP directory", a);
760 strprompt("Host name of LDAP server",
762 strprompt("Port number of LDAP service",
764 strprompt("Base DN", &sc[34][0], 255);
765 strprompt("Bind DN", &sc[35][0], 255);
766 strprompt("Password for bind DN", &sc[36][0], 255);
769 strcpy(&sc[32][0], "");
773 /* Expiry settings */
774 strprompt("Default user purge time (days)", &sc[16][0], 5);
775 strprompt("Default room purge time (days)", &sc[17][0], 5);
777 /* Angels and demons dancing in my head... */
779 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_mode);
780 strprompt("System default message expire policy (? for list)",
784 "1. Never automatically expire messages\n"
785 "2. Expire by message count\n"
786 "3. Expire by message age\n");
788 } while ((buf[0] < '1') || (buf[0] > '3'));
789 site_expirepolicy->expire_mode = buf[0] - '0';
791 /* ...lunatics and monsters underneath my bed */
792 if (site_expirepolicy->expire_mode == 2) {
793 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
794 strprompt("Keep how many messages online?", buf, 10);
795 site_expirepolicy->expire_value = atol(buf);
797 if (site_expirepolicy->expire_mode == 3) {
798 snprintf(buf, sizeof buf, "%d", site_expirepolicy->expire_value);
799 strprompt("Keep messages for how many days?", buf, 10);
800 site_expirepolicy->expire_value = atol(buf);
803 /* Media messiahs preying on my fears... */
805 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_mode);
806 strprompt("Mailbox default message expire policy (? for list)",
810 "0. Go with the system default\n"
811 "1. Never automatically expire messages\n"
812 "2. Expire by message count\n"
813 "3. Expire by message age\n");
815 } while ((buf[0] < '0') || (buf[0] > '3'));
816 mbx_expirepolicy->expire_mode = buf[0] - '0';
818 /* ...Pop culture prophets playing in my ears */
819 if (mbx_expirepolicy->expire_mode == 2) {
820 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
821 strprompt("Keep how many messages online?", buf, 10);
822 mbx_expirepolicy->expire_value = atol(buf);
824 if (mbx_expirepolicy->expire_mode == 3) {
825 snprintf(buf, sizeof buf, "%d", mbx_expirepolicy->expire_value);
826 strprompt("Keep messages for how many days?", buf, 10);
827 mbx_expirepolicy->expire_value = atol(buf);
830 strprompt("How often to run network jobs (in seconds)", &sc[28][0], 5);
831 strprompt("Hour to run purges (0-23)", &sc[31][0], 2);
834 scr_printf("Save this configuration? ");
837 for (a = 0; a < NUM_CONFIGS; a++)
838 r += 1 + strlen(sc[a]);
839 resp = (char *)calloc(1, r);
841 err_printf("Can't save config - out of memory!\n");
844 for (a = 0; a < NUM_CONFIGS; a++) {
848 r = CtdlIPCSetSystemConfig(ipc, resp, buf);
850 err_printf("%s\n", buf);
854 r = CtdlIPCSetMessageExpirationPolicy(ipc, 2, site_expirepolicy, buf);
856 err_printf("%s\n", buf);
859 r = CtdlIPCSetMessageExpirationPolicy(ipc, 3, mbx_expirepolicy, buf);
861 err_printf("%s\n", buf);
869 * support function for do_internet_configuration()
871 void get_inet_rec_type(CtdlIPC *ipc, char *buf) {
874 keyopt(" <1> localhost (Alias for this computer)\n");
875 keyopt(" <2> gateway domain (Domain for all Citadel systems)\n");
876 keyopt(" <3> smart-host (Forward all outbound mail to this host)\n");
877 keyopt(" <4> directory (Consult the Global Address Book)\n");
878 keyopt(" <5> SpamAssassin (Address of SpamAssassin server)\n");
879 keyopt(" <6> RBL (domain suffix of spam hunting RBL)\n");
880 sel = intprompt("Which one", 1, 1, 6);
882 case 1: strcpy(buf, "localhost");
884 case 2: strcpy(buf, "gatewaydomain");
886 case 3: strcpy(buf, "smarthost");
888 case 4: strcpy(buf, "directory");
890 case 5: strcpy(buf, "spamassassin");
892 case 6: strcpy(buf, "rbl");
899 * Internet mail configuration
901 void do_internet_configuration(CtdlIPC *ipc)
913 r = CtdlIPCGetSystemConfigByType(ipc, INTERNETCFG, &resp, buf);
915 while (strlen(resp)) {
916 extract_token(buf, resp, 0, '\n');
917 remove_token(resp, 0, '\n');
919 if (num_recs == 1) recs = malloc(sizeof(char *));
920 else recs = realloc(recs, (sizeof(char *)) * num_recs);
921 recs[num_recs-1] = malloc(strlen(buf) + 1);
922 strcpy(recs[num_recs-1], buf);
925 if (resp) free(resp);
930 scr_printf("### Host or domain Record type \n");
932 scr_printf("--- -------------------------------------------------- --------------------\n");
933 for (i=0; i<num_recs; ++i) {
935 scr_printf("%3d ", i+1);
936 extract(buf, recs[i], 0);
938 scr_printf("%-50s ", buf);
939 extract(buf, recs[i], 1);
940 color(BRIGHT_MAGENTA);
941 scr_printf("%-20s\n", buf);
945 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
948 newprompt("Enter host name: ",
951 if (strlen(buf) > 0) {
954 recs = malloc(sizeof(char *));
955 else recs = realloc(recs,
956 (sizeof(char *)) * num_recs);
958 get_inet_rec_type(ipc,
960 recs[num_recs-1] = strdup(buf);
964 i = intprompt("Delete which one",
968 for (j=i; j<num_recs; ++j)
973 for (i = 0; i < num_recs; i++)
974 r += 1 + strlen(recs[i]);
975 resp = (char *)calloc(1, r);
977 err_printf("Can't save config - out of memory!\n");
980 if (num_recs) for (i = 0; i < num_recs; i++) {
981 strcat(resp, recs[i]);
984 r = CtdlIPCSetSystemConfigByType(ipc, INTERNETCFG, resp, buf);
986 err_printf("%s\n", buf);
991 quitting = boolprompt(
992 "Quit without saving", 0);
997 } while (quitting == 0);
1000 for (i=0; i<num_recs; ++i) free(recs[i]);
1008 * Edit network configuration for room sharing, mailing lists, etc.
1010 void network_config_management(CtdlIPC *ipc, char *entrytype, char *comment)
1012 char filename[PATH_MAX];
1013 char changefile[PATH_MAX];
1023 char *listing = NULL;
1026 if (strlen(editor_paths[0]) == 0) {
1027 scr_printf("You must have an external editor configured in"
1028 " order to use this function.\n");
1032 snprintf(filename, sizeof filename, "%s.listedit", tmpnam(NULL));
1033 snprintf(changefile, sizeof changefile, "%s.listedit", tmpnam(NULL));
1035 tempfp = fopen(filename, "w");
1036 if (tempfp == NULL) {
1037 err_printf("Cannot open %s: %s\n", filename, strerror(errno));
1041 fprintf(tempfp, "# Configuration for room: %s\n", room_name);
1042 fprintf(tempfp, "# %s\n", comment);
1043 fprintf(tempfp, "# Specify one per line.\n"
1046 r = CtdlIPCGetRoomNetworkConfig(ipc, &listing, buf);
1048 while(listing && strlen(listing)) {
1049 extract_token(buf, listing, 0, '\n');
1050 remove_token(listing, 0, '\n');
1051 extract(instr, buf, 0);
1052 if (!strcasecmp(instr, entrytype)) {
1053 extract(addr, buf, 1);
1054 fprintf(tempfp, "%s\n", addr);
1064 e_ex_code = 1; /* start with a failed exit code */
1066 sttybbs(SB_RESTORE);
1067 editor_pid = fork();
1068 cksum = file_checksum(filename);
1069 if (editor_pid == 0) {
1070 chmod(filename, 0600);
1071 putenv("WINDOW_TITLE=Network configuration");
1072 execlp(editor_paths[0], editor_paths[0], filename, NULL);
1075 if (editor_pid > 0) {
1078 b = ka_wait(&e_ex_code);
1079 } while ((b != editor_pid) && (b >= 0));
1085 if (file_checksum(filename) == cksum) {
1086 err_printf("*** Not saving changes.\n");
1090 if (e_ex_code == 0) { /* Save changes */
1091 changefp = fopen(changefile, "w");
1092 CtdlIPC_putline(ipc, "GNET");
1093 CtdlIPC_getline(ipc, buf);
1094 if (buf[0] == '1') {
1095 while(CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) {
1096 extract(instr, buf, 0);
1097 if (strcasecmp(instr, entrytype)) {
1098 fprintf(changefp, "%s\n", buf);
1102 tempfp = fopen(filename, "r");
1103 while (fgets(buf, sizeof buf, tempfp) != NULL) {
1104 for (i=0; i<strlen(buf); ++i) {
1105 if (buf[i] == '#') buf[i] = 0;
1108 if (strlen(buf) > 0) {
1109 fprintf(changefp, "%s|%s\n", entrytype, buf);
1115 /* now write it to the server... */
1116 CtdlIPC_putline(ipc, "SNET");
1117 CtdlIPC_getline(ipc, buf);
1118 if (buf[0] == '4') {
1119 changefp = fopen(changefile, "r");
1120 if (changefp != NULL) {
1121 while (fgets(buf, sizeof buf,
1122 changefp) != NULL) {
1123 buf[strlen(buf) - 1] = 0;
1124 CtdlIPC_putline(ipc, buf);
1128 CtdlIPC_putline(ipc, "000");
1132 unlink(filename); /* Delete the temporary files */
1138 * IGnet node configuration
1140 void do_ignet_configuration(CtdlIPC *ipc) {
1148 char *listing = NULL;
1151 r = CtdlIPCGetSystemConfigByType(ipc, IGNETCFG, listing, buf);
1152 if (r / 100 == 1) while (*listing && strlen(listing)) {
1153 extract_token(buf, listing, 0, '\n');
1154 remove_token(listing, 0, '\n');
1157 if (num_recs == 1) recs = malloc(sizeof(char *));
1158 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1159 recs[num_recs-1] = malloc(SIZ);
1160 strcpy(recs[num_recs-1], buf);
1162 if (listing) free(listing);
1166 color(BRIGHT_WHITE);
1175 "------------------ "
1176 "-------------------------------- "
1178 for (i=0; i<num_recs; ++i) {
1180 scr_printf("%3d ", i+1);
1181 extract(buf, recs[i], 0);
1183 scr_printf("%-16s ", buf);
1184 extract(buf, recs[i], 1);
1185 color(BRIGHT_MAGENTA);
1186 scr_printf("%-18s ", buf);
1187 extract(buf, recs[i], 2);
1189 scr_printf("%-32s ", buf);
1190 extract(buf, recs[i], 3);
1191 color(BRIGHT_MAGENTA);
1192 scr_printf("%-3s\n", buf);
1196 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1201 recs = malloc(sizeof(char *));
1202 else recs = realloc(recs,
1203 (sizeof(char *)) * num_recs);
1204 newprompt("Enter node name : ", buf, 16);
1206 newprompt("Enter shared secret: ",
1207 &buf[strlen(buf)], 18);
1209 newprompt("Enter host or IP : ",
1210 &buf[strlen(buf)], 32);
1211 strcat(buf, "|504");
1212 strprompt("Enter port number : ",
1213 &buf[strlen(buf)-3], 5);
1214 recs[num_recs-1] = strdup(buf);
1217 i = intprompt("Delete which one",
1218 1, 1, num_recs) - 1;
1221 for (j=i; j<num_recs; ++j)
1222 recs[j] = recs[j+1];
1226 for (i = 0; i < num_recs; ++i)
1227 r += 1 + strlen(recs[i]);
1228 listing = (char*) calloc(1, r);
1230 err_printf("Can't save config - out of memory!\n");
1233 if (num_recs) for (i = 0; i < num_recs; ++i) {
1234 strcat(listing, recs[i]);
1235 strcat(listing, "\n");
1237 r = CtdlIPCSetSystemConfigByType(ipc, IGNETCFG, listing, buf);
1239 scr_printf("%s\n", buf);
1244 quitting = boolprompt(
1245 "Quit without saving", 0);
1250 } while (quitting == 0);
1253 for (i=0; i<num_recs; ++i) free(recs[i]);
1259 * Filter list configuration
1261 void do_filterlist_configuration(CtdlIPC *ipc)
1270 char *listing = NULL;
1273 r = CtdlIPCGetSystemConfigByType(ipc, FILTERLIST, listing, buf);
1274 if (r / 100 == 1) while (*listing && strlen(listing)) {
1275 extract_token(buf, listing, 0, '\n');
1276 remove_token(listing, 0, '\n');
1279 if (num_recs == 1) recs = malloc(sizeof(char *));
1280 else recs = realloc(recs, (sizeof(char *)) * num_recs);
1281 recs[num_recs-1] = malloc(SIZ);
1282 strcpy(recs[num_recs-1], buf);
1284 if (listing) free(listing);
1288 color(BRIGHT_WHITE);
1296 "---------------------------- "
1297 "---------------------------- "
1300 for (i=0; i<num_recs; ++i) {
1302 scr_printf("%3d ", i+1);
1303 extract(buf, recs[i], 0);
1305 scr_printf("%-28s ", buf);
1306 extract(buf, recs[i], 1);
1307 color(BRIGHT_MAGENTA);
1308 scr_printf("%-28s ", buf);
1309 extract(buf, recs[i], 2);
1311 scr_printf("%-16s\n", buf);
1312 extract(buf, recs[i], 3);
1316 ch = keymenu("", "<A>dd|<D>elete|<S>ave|<Q>uit");
1321 recs = malloc(sizeof(char *));
1322 else recs = realloc(recs,
1323 (sizeof(char *)) * num_recs);
1324 newprompt("Enter user name: ", buf, 28);
1326 newprompt("Enter room name: ",
1327 &buf[strlen(buf)], 28);
1329 newprompt("Enter node name: ",
1330 &buf[strlen(buf)], 16);
1332 recs[num_recs-1] = strdup(buf);
1335 i = intprompt("Delete which one",
1336 1, 1, num_recs) - 1;
1339 for (j=i; j<num_recs; ++j)
1340 recs[j] = recs[j+1];
1344 for (i = 0; i < num_recs; ++i)
1345 r += 1 + strlen(recs[i]);
1346 listing = (char*) calloc(1, r);
1348 err_printf("Can't save config - out of memory!\n");
1351 if (num_recs) for (i = 0; i < num_recs; ++i) {
1352 strcat(listing, recs[i]);
1353 strcat(listing, "\n");
1355 r = CtdlIPCSetSystemConfigByType(ipc, FILTERLIST, listing, buf);
1357 scr_printf("%s\n", buf);
1362 quitting = boolprompt(
1363 "Quit without saving", 0);
1368 } while (quitting == 0);
1371 for (i=0; i<num_recs; ++i) free(recs[i]);