1 /* More Citadel/UX routines...
2 * unlike routines.c, some of these DO use global variables.
22 #include "routines2.h"
31 void interr(int errnum);
32 void strprompt(char *prompt, char *str, int len);
33 void newprompt(char *prompt, char *str, int len);
34 void sttybbs(int cmd);
36 void serv_write(char *buf, int nbytes);
37 int haschar(char *st, int ch);
38 void progress(long int curr, long int cmax);
39 void citedit(FILE * fp, long int base_pos);
43 extern char tempdir[];
44 extern char *axdefs[7];
45 extern long highest_msg_read;
46 extern long maxmsgnum;
47 extern unsigned room_flags;
48 extern int screenwidth;
51 int eopen(char *name, int mode)
54 ret = open(name, mode);
56 fprintf(stderr, "Cannot open file '%s', mode=%d, errno=%d\n",
64 int room_prompt(int qrflags)
65 { /* return proper room prompt character */
68 if (qrflags & QR_DIRECTORY)
70 if ((a == ']') && (qrflags & QR_NETWORK))
72 if ((a == '>') && (qrflags & QR_NETWORK))
78 { /* register with name and address */
98 serv_puts("GREG _SELF_");
102 while (serv_gets(buf), strcmp(buf, "000")) {
104 strcpy(tmpname, buf);
106 strcpy(tmpaddr, buf);
108 strcpy(tmpcity, buf);
110 strcpy(tmpstate, buf);
114 strcpy(tmpphone, buf);
116 strcpy(tmpemail, buf);
120 strprompt("REAL name", tmpname, 29);
121 strprompt("Address", tmpaddr, 24);
122 strprompt("City/town", tmpcity, 14);
123 strprompt("State", tmpstate, 2);
124 strprompt("ZIP Code", tmpzip, 10);
125 strprompt("Telephone number", tmpphone, 14);
126 strprompt("Email address", tmpemail, 31);
128 /* now send the registration info back to the server */
132 printf("%s\n", &buf[4]);
147 { /* make all messages old in current room */
149 serv_puts("SLRP HIGHEST");
152 printf("%s\n", &buf[4]);
156 * only make messages old in this room that have been read
161 sprintf(buf, "SLRP %ld", highest_msg_read);
165 printf("%s\n", &buf[4]);
170 * This routine completes a client upload
172 void do_upload(int fd)
176 long transmitted_bytes, total_bytes;
180 /* learn the size of the file */
181 total_bytes = lseek(fd, 0L, 2);
184 transmitted_bytes = 0L;
185 progress(transmitted_bytes, total_bytes);
187 bytes_to_send = read(fd, tbuf, 4096);
188 if (bytes_to_send > 0) {
189 sprintf(buf, "WRIT %d", bytes_to_send);
193 bytes_expected = atoi(&buf[4]);
194 serv_write(tbuf, bytes_expected);
196 printf("%s\n", &buf[4]);
199 transmitted_bytes = transmitted_bytes + (long) bytes_to_send;
200 progress(transmitted_bytes, total_bytes);
201 } while (bytes_to_send > 0);
203 /* close the upload file, locally and at the server */
207 printf("%s\n", &buf[4]);
212 * client-based uploads (for users with their own clientware)
214 void cli_upload(void)
223 if ((room_flags & QR_UPLOAD) == 0) {
224 printf("*** You cannot upload to this room.\n");
227 newprompt("File to be uploaded: ", flnm, 55);
228 fd = open(flnm, O_RDONLY);
230 printf("Cannot open '%s': %s\n", flnm, strerror(errno));
233 printf("Enter a description of this file:\n");
234 newprompt(": ", desc, 75);
236 /* keep generating filenames in hope of finding a unique one */
240 return; /* fail if tried 10 times */
242 while ((strlen(buf) > 0) && (haschar(buf, '/')))
243 strcpy(buf, &buf[1]);
245 sprintf(&buf[strlen(buf)], "%d", a);
246 sprintf(tbuf, "UOPN %s|%s", buf, desc);
250 printf("%s\n", &buf[4]);
252 } while (buf[0] != '2');
254 /* at this point we have an open upload file at the server */
260 * Function used for various image upload commands
262 void cli_image_upload(char *keyname)
268 sprintf(buf, "UIMG 0|%s", keyname);
272 printf("%s\n", &buf[4]);
275 newprompt("Image file to be uploaded: ", flnm, 55);
276 fd = open(flnm, O_RDONLY);
278 printf("Cannot open '%s': %s\n", flnm, strerror(errno));
281 sprintf(buf, "UIMG 1|%s", keyname);
285 printf("%s\n", &buf[4]);
293 * protocol-based uploads (Xmodem, Ymodem, Zmodem)
296 { /* c = upload mode */
306 if ((room_flags & QR_UPLOAD) == 0) {
307 printf("*** You cannot upload to this room.\n");
310 /* we don't need a filename when receiving batch y/z modem */
311 if ((c == 2) || (c == 3))
314 newprompt("Enter filename: ", flnm, 15);
316 for (a = 0; a < strlen(flnm); ++a)
317 if ((flnm[a] == '/') || (flnm[a] == '\\') || (flnm[a] == '>')
318 || (flnm[a] == '?') || (flnm[a] == '*')
319 || (flnm[a] == ';') || (flnm[a] == '&'))
322 newprompt("Enter a short description of the file:\n: ", desc, 150);
324 /* create a temporary directory... */
325 if (mkdir(tempdir, 0700) != 0) {
326 printf("*** Could not create temporary directory %s: %s\n",
327 tempdir, strerror(errno));
330 /* now do the transfer ... in a separate process */
337 printf("Receiving %s - press Ctrl-D to end.\n", flnm);
338 fp = fopen(flnm, "w");
354 execlp("rx", "rx", flnm, NULL);
358 execlp("rb", "rb", NULL);
362 execlp("rz", "rz", NULL);
368 } while ((b != xfer_pid) && (b != (-1)));
372 printf("\r*** Transfer unsuccessful.\n");
376 printf("\r*** Transfer successful. Sending file(s) to server...\n");
377 sprintf(buf, "cd %s; ls", tempdir);
378 lsfp = popen(buf, "r");
380 while (fgets(flnm, 256, lsfp) != NULL) {
381 flnm[strlen(flnm) - 1] = 0;
382 sprintf(buf, "%s/%s", tempdir, flnm);
383 fd = open(buf, O_RDONLY);
387 sprintf(buf, "UOPN %s|%s", flnm, desc);
389 sprintf(&buf[strlen(buf)],
394 } while ((buf[0] != '2') && (a < 100));
397 a = read(fd, tbuf, 4096);
399 sprintf(buf, "WRIT %d", a);
409 printf("%s\n", &buf[4]);
420 void val_user(char *user, int do_validate)
427 sprintf(cmd, "GREG %s", user);
436 printf("User #%s - %s ", buf, &cmd[4]);
438 printf("PW: %s\n", buf);
455 } while (strcmp(buf, "000"));
456 printf("Current access level: %d (%s)\n", ax, axdefs[ax]);
458 printf("%-30s\n%s\n", user, &cmd[4]);
462 /* now set the access level */
463 ax = intprompt("Access level", ax, 0, 6);
464 sprintf(cmd, "VALI %s|%d", user, ax);
468 printf("%s\n", &cmd[4]);
475 { /* validate new users */
486 printf("%s\n", &cmd[4]);
488 extract(buf, cmd, 0);
489 val_user(&buf[4], 1);
491 } while (finished == 0);
500 signal(SIGINT, SIG_DFL);
501 signal(SIGQUIT, SIG_DFL);
502 execlp(getenv("SHELL"), getenv("SHELL"), NULL);
503 printf("Could not open a shell: %s\n", strerror(errno));
508 } while ((a != b) && (a != (-1)));
513 * <.A>ide <F>ile <D>elete command
515 void deletefile(void)
520 newprompt("Filename: ", filename, 31);
521 if (strlen(filename) == 0)
523 sprintf(cmd, "DELF %s", filename);
526 printf("%s\n", &cmd[4]);
530 * <.A>ide <F>ile <S>end command
532 void netsendfile(void)
534 char filename[32], destsys[20], cmd[256];
536 newprompt("Filename: ", filename, 31);
537 if (strlen(filename) == 0)
539 newprompt("System to send to: ", destsys, 19);
540 sprintf(cmd, "NETF %s|%s", filename, destsys);
543 printf("%s\n", &cmd[4]);
548 * <.A>ide <F>ile <M>ove command
553 char newroom[ROOMNAMELEN];
556 newprompt("Filename: ", filename, 63);
557 if (strlen(filename) == 0)
559 newprompt("Enter target room: ", newroom, ROOMNAMELEN - 1);
561 sprintf(cmd, "MOVF %s|%s", filename, newroom);
564 printf("%s\n", &cmd[4]);
569 * list of users who have filled out a bio
579 printf("%s\n", &buf[4]);
582 while (serv_gets(buf), strcmp(buf, "000")) {
583 if ((pos + strlen(buf) + 5) > screenwidth) {
588 pos = pos + strlen(buf) + 2;
590 printf("%c%c \n\n", 8, 8);
603 newprompt("Read bio for who ('?' for list) : ", who, 25);
605 if (!strcmp(who, "?"))
607 } while (!strcmp(who, "?"));
608 sprintf(buf, "RBIO %s", who);
612 printf("%s\n", &buf[4]);
615 while (serv_gets(buf), strcmp(buf, "000")) {
622 * General system configuration command
624 void do_system_configuration(void)
629 int expire_value = 0;
632 /* Clear out the config buffers */
633 memset(&sc[0][0], 0, sizeof(sc));
635 /* Fetch the current config */
636 serv_puts("CONF get");
640 while (serv_gets(buf), strcmp(buf, "000")) {
642 strcpy(&sc[a][0], buf);
646 /* Fetch the expire policy (this will silently fail on old servers,
647 * resulting in "default" policy)
649 serv_puts("GPEX site");
652 expire_mode = extract_int(&buf[4], 0);
653 expire_value = extract_int(&buf[4], 1);
655 strprompt("Node name", &sc[0][0], 15);
656 strprompt("Fully qualified domain name", &sc[1][0], 63);
657 strprompt("Human readable node name", &sc[2][0], 20);
658 strprompt("Modem dialup number", &sc[3][0], 15);
660 sprintf(&sc[4][0], "%d", (boolprompt(
661 "Automatically give room aide privs to a user who creates a private room",
664 strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4);
665 strprompt("Initial access level for new users", &sc[6][0], 1);
666 strprompt("Access level required to create rooms", &sc[19][0], 1);
668 sprintf(&sc[7][0], "%d", (boolprompt(
669 "Require registration for new users",
672 sprintf(&sc[8][0], "%d", (boolprompt(
673 "Automatically move problem user messages to twit room",
676 strprompt("Name of twit room", &sc[9][0], ROOMNAMELEN);
677 strprompt("Paginator prompt", &sc[10][0], 79);
679 sprintf(&sc[11][0], "%d", (boolprompt(
680 "Restrict Internet mail to only those with that privilege",
683 strprompt("Geographic location of this system", &sc[12][0], 31);
684 strprompt("Name of system administrator", &sc[13][0], 25);
685 strprompt("Maximum concurrent sessions", &sc[14][0], 4);
686 strprompt("Server-to-server networking password", &sc[15][0], 19);
687 strprompt("Default user purge time (days)", &sc[16][0], 5);
688 strprompt("Default room purge time (days)", &sc[17][0], 5);
689 strprompt("Name of room to log pages", &sc[18][0], ROOMNAMELEN);
690 strprompt("Maximum message length", &sc[20][0], 20);
691 strprompt("Minimum number of worker threads", &sc[21][0], 3);
692 strprompt("Maximum number of worker threads", &sc[22][0], 3);
694 /* Angels and demons dancing in my head... */
696 sprintf(buf, "%d", expire_mode);
697 strprompt("System default message expire policy (? for list)",
701 printf("1. Never automatically expire messages\n");
702 printf("2. Expire by message count\n");
703 printf("3. Expire by message age\n");
705 } while ((buf[0] < 49) || (buf[0] > 51));
706 expire_mode = buf[0] - 48;
708 /* ...lunatics and monsters underneath my bed */
709 if (expire_mode == 2) {
710 sprintf(buf, "%d", expire_value);
711 strprompt("Keep how many messages online?", buf, 10);
712 expire_value = atol(buf);
714 if (expire_mode == 3) {
715 sprintf(buf, "%d", expire_value);
716 strprompt("Keep messages for how many days?", buf, 10);
717 expire_value = atol(buf);
720 printf("Save this configuration? ");
722 serv_puts("CONF set");
725 for (a = 0; a < 23; ++a)
726 serv_puts(&sc[a][0]);
729 snprintf(buf, sizeof buf, "SPEX site|%d|%d",
730 expire_mode, expire_value);