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) /* return proper room prompt character */
68 if (qrflags&QR_DIRECTORY) a=']';
69 if ((a==']')&&(qrflags&QR_NETWORK)) a='}';
70 if ((a=='>')&&(qrflags&QR_NETWORK)) a=')';
74 void entregis(void) /* register with name and address */
95 serv_puts("GREG _SELF_");
99 while (serv_gets(buf), strcmp(buf,"000")) {
100 if (a==2) strcpy(tmpname,buf);
101 if (a==3) strcpy(tmpaddr,buf);
102 if (a==4) strcpy(tmpcity,buf);
103 if (a==5) strcpy(tmpstate,buf);
104 if (a==6) strcpy(tmpzip,buf);
105 if (a==7) strcpy(tmpphone,buf);
106 if (a==9) strcpy(tmpemail,buf);
111 strprompt("REAL name",tmpname,29);
112 strprompt("Address",tmpaddr,24);
113 strprompt("City/town",tmpcity,14);
114 strprompt("State",tmpstate,2);
115 strprompt("ZIP Code",tmpzip,10);
116 strprompt("Telephone number",tmpphone,14);
117 strprompt("Email address",tmpemail,31);
119 /* now send the registration info back to the server */
123 printf("%s\n",&buf[4]);
137 void updatels(void) { /* make all messages old in current room */
139 serv_puts("SLRP HIGHEST");
141 if (buf[0]!='2') printf("%s\n",&buf[4]);
144 void updatelsa(void) { /* only make messages old in this room that have been read */
146 sprintf(buf,"SLRP %ld",highest_msg_read);
149 if (buf[0]!='2') printf("%s\n",&buf[4]);
154 * This routine completes a client upload
156 void do_upload(int fd) {
159 long transmitted_bytes, total_bytes;
163 /* learn the size of the file */
164 total_bytes = lseek(fd,0L,2);
167 transmitted_bytes = 0L;
168 progress(transmitted_bytes,total_bytes);
170 bytes_to_send = read(fd,tbuf,4096);
171 if (bytes_to_send>0) {
172 sprintf(buf,"WRIT %d",bytes_to_send);
176 bytes_expected = atoi(&buf[4]);
177 serv_write(tbuf,bytes_expected);
180 printf("%s\n",&buf[4]);
183 transmitted_bytes = transmitted_bytes + (long)bytes_to_send;
184 progress(transmitted_bytes, total_bytes);
185 } while (bytes_to_send > 0);
187 /* close the upload file, locally and at the server */
191 printf("%s\n",&buf[4]);
196 * client-based uploads (for users with their own clientware)
198 void cli_upload(void) {
206 if ((room_flags & QR_UPLOAD) == 0) {
207 printf("*** You cannot upload to this room.\n");
211 newprompt("File to be uploaded: ",flnm,55);
212 fd = open(flnm,O_RDONLY);
214 printf("Cannot open '%s': %s\n",flnm,strerror(errno));
217 printf("Enter a description of this file:\n");
218 newprompt(": ",desc,75);
220 /* keep generating filenames in hope of finding a unique one */
223 if (a==10) return; /* fail if tried 10 times */
225 while ((strlen(buf)>0)&&(haschar(buf,'/')))
227 if (a>0) sprintf(&buf[strlen(buf)],"%d",a);
228 sprintf(tbuf,"UOPN %s|%s",buf,desc);
231 if (buf[0]!='2') printf("%s\n",&buf[4]);
233 } while (buf[0]!='2');
235 /* at this point we have an open upload file at the server */
241 * Function used for various image upload commands
243 void cli_image_upload(char *keyname) {
248 sprintf(buf, "UIMG 0|%s", keyname);
252 printf("%s\n", &buf[4]);
256 newprompt("Image file to be uploaded: ",flnm,55);
257 fd = open(flnm,O_RDONLY);
259 printf("Cannot open '%s': %s\n",flnm,strerror(errno));
263 sprintf(buf, "UIMG 1|%s", keyname);
267 printf("%s\n", &buf[4]);
276 * protocol-based uploads (Xmodem, Ymodem, Zmodem)
278 void upload(int c) /* c = upload mode */
289 if ((room_flags & QR_UPLOAD) == 0) {
290 printf("*** You cannot upload to this room.\n");
294 /* we don't need a filename when receiving batch y/z modem */
295 if ((c==2)||(c==3)) strcpy(flnm,"x");
296 else newprompt("Enter filename: ",flnm,15);
298 for (a=0; a<strlen(flnm); ++a)
299 if ( (flnm[a]=='/') || (flnm[a]=='\\') || (flnm[a]=='>')
300 || (flnm[a]=='?') || (flnm[a]=='*')
301 || (flnm[a]==';') || (flnm[a]=='&') ) flnm[a]='_';
303 newprompt("Enter a short description of the file:\n: ",desc,150);
305 /* create a temporary directory... */
306 if (mkdir(tempdir,0700) != 0) {
307 printf("*** Could not create temporary directory %s: %s\n",
308 tempdir,strerror(errno));
312 /* now do the transfer ... in a separate process */
319 printf("Receiving %s - press Ctrl-D to end.\n",flnm);
320 fp = fopen(flnm,"w");
335 execlp("rx","rx",flnm,NULL);
339 execlp("rb","rb",NULL);
343 execlp("rz","rz",NULL);
349 } while ((b!=xfer_pid)&&(b!=(-1)));
353 printf("\r*** Transfer unsuccessful.\n");
358 printf("\r*** Transfer successful. Sending file(s) to server...\n");
359 sprintf(buf,"cd %s; ls",tempdir);
360 lsfp = popen(buf,"r");
362 while (fgets(flnm,256,lsfp)!=NULL) {
363 flnm[strlen(flnm)-1] = 0;
364 sprintf(buf,"%s/%s",tempdir,flnm);
365 fd = open(buf,O_RDONLY);
369 sprintf(buf,"UOPN %s|%s",flnm,desc);
370 if (a>0) sprintf(&buf[strlen(buf)],
375 } while((buf[0]!='2')&&(a<100));
376 if (buf[0]=='2') do {
377 a=read(fd,tbuf,4096);
379 sprintf(buf,"WRIT %d",a);
389 printf("%s\n",&buf[4]);
401 void val_user(char *user, int do_validate)
408 sprintf(cmd, "GREG %s", user);
416 if (a==1) printf("User #%s - %s ", buf, &cmd[4]);
417 if (a==2) printf("PW: %s\n",buf);
418 if (a==3) printf("%s\n",buf);
419 if (a==4) printf("%s\n",buf);
420 if (a==5) printf("%s, ",buf);
421 if (a==6) printf("%s ",buf);
422 if (a==7) printf("%s\n",buf);
423 if (a==8) printf("%s\n",buf);
424 if (a==9) ax=atoi(buf);
425 if (a==10) printf("%s\n",buf);
426 } while(strcmp(buf,"000"));
427 printf("Current access level: %d (%s)\n",ax,axdefs[ax]);
430 printf("%-30s\n%s\n",user,&cmd[4]);
434 /* now set the access level */
435 ax = intprompt("Access level", ax, 0, 6);
436 sprintf(cmd,"VALI %s|%d",user,ax);
439 if (cmd[0]!='2') printf("%s\n",&cmd[4]);
445 void validate(void) { /* validate new users */
453 if (cmd[0]!='3') finished = 1;
454 if (cmd[0]=='2') printf("%s\n",&cmd[4]);
456 extract(buf, cmd, 0);
457 val_user(&buf[4], 1);
459 } while(finished==0);
462 void subshell(void) {
467 signal(SIGINT,SIG_DFL);
468 signal(SIGQUIT,SIG_DFL);
469 execlp(getenv("SHELL"),getenv("SHELL"),NULL);
470 printf("Could not open a shell: %s\n", strerror(errno));
475 } while ((a!=b)&&(a!=(-1)));
480 * <.A>ide <F>ile <D>elete command
482 void deletefile(void) {
486 newprompt("Filename: ",filename,31);
487 if (strlen(filename)==0) return;
488 sprintf(cmd,"DELF %s",filename);
491 printf("%s\n",&cmd[4]);
495 * <.A>ide <F>ile <S>end command
497 void netsendfile(void) {
498 char filename[32],destsys[20],cmd[256];
500 newprompt("Filename: ",filename,31);
501 if (strlen(filename)==0) return;
502 newprompt("System to send to: ",destsys,19);
503 sprintf(cmd,"NETF %s|%s",filename,destsys);
506 printf("%s\n",&cmd[4]);
511 * <.A>ide <F>ile <M>ove command
513 void movefile(void) {
515 char newroom[ROOMNAMELEN];
518 newprompt("Filename: ",filename,63);
519 if (strlen(filename)==0) return;
520 newprompt("Enter target room: ",newroom,ROOMNAMELEN-1);
522 sprintf(cmd,"MOVF %s|%s",filename,newroom);
525 printf("%s\n",&cmd[4]);
530 * list of users who have filled out a bio
532 void list_bio(void) {
539 printf("%s\n",&buf[4]);
542 while (serv_gets(buf), strcmp(buf,"000")) {
543 if ((pos+strlen(buf)+5)>screenwidth) {
548 pos = pos + strlen(buf) + 2;
550 printf("%c%c \n\n",8,8);
557 void read_bio(void) {
562 newprompt("Read bio for who ('?' for list) : ",who,25);
564 if (!strcmp(who,"?")) list_bio();
565 } while(!strcmp(who,"?"));
566 sprintf(buf,"RBIO %s",who);
570 printf("%s\n",&buf[4]);
573 while (serv_gets(buf), strcmp(buf,"000")) {
580 * General system configuration command
582 void do_system_configuration(void) {
586 int expire_value = 0;
589 /* Clear out the config buffers */
590 memset(&sc[0][0], 0, sizeof(sc));
592 /* Fetch the current config */
593 serv_puts("CONF get");
597 while (serv_gets(buf), strcmp(buf, "000")) {
598 if (a<21) strcpy(&sc[a][0], buf);
603 /* Fetch the expire policy (this will silently fail on old servers,
604 * resulting in "default" policy)
606 serv_puts("GPEX site");
609 expire_mode = extract_int(&buf[4], 0);
610 expire_value = extract_int(&buf[4], 1);
613 strprompt("Node name", &sc[0][0], 15);
614 strprompt("Fully qualified domain name", &sc[1][0], 63);
615 strprompt("Human readable node name", &sc[2][0], 20);
616 strprompt("Modem dialup number", &sc[3][0], 15);
618 sprintf(&sc[4][0], "%d", (boolprompt(
619 "Automatically give room aide privs to a user who creates a private room",
622 strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4);
623 strprompt("Initial access level for new users", &sc[6][0], 1);
624 strprompt("Access level required to create rooms", &sc[19][0], 1);
626 sprintf(&sc[7][0], "%d", (boolprompt(
627 "Require registration for new users",
630 sprintf(&sc[8][0], "%d", (boolprompt(
631 "Automatically move problem user messages to twit room",
634 strprompt("Name of twit room", &sc[9][0], ROOMNAMELEN);
635 strprompt("Paginator prompt", &sc[10][0], 79);
637 sprintf(&sc[11][0], "%d", (boolprompt(
638 "Restrict Internet mail to only those with that privilege",
641 strprompt("Geographic location of this system", &sc[12][0], 31);
642 strprompt("Name of system administrator", &sc[13][0], 25);
643 strprompt("Maximum concurrent sessions", &sc[14][0], 4);
644 strprompt("Server-to-server networking password", &sc[15][0], 19);
645 strprompt("Default user purge time (days)", &sc[16][0], 5);
646 strprompt("Default room purge time (days)", &sc[17][0], 5);
647 strprompt("Name of room to log pages", &sc[18][0], ROOMNAMELEN);
648 strprompt("Maximum message length", &sc[20][0], 20);
650 /* Angels and demons dancing in my head... */
652 sprintf(buf, "%d", expire_mode);
653 strprompt("System default message expire policy (? for list)",
657 printf("1. Never automatically expire messages\n");
658 printf("2. Expire by message count\n");
659 printf("3. Expire by message age\n");
661 } while((buf[0]<49)||(buf[0]>51));
662 expire_mode = buf[0] - 48;
664 /* ...lunatics and monsters underneath my bed */
665 if (expire_mode == 2) {
666 sprintf(buf, "%d", expire_value);
667 strprompt("Keep how many messages online?", buf, 10);
668 expire_value = atol(buf);
671 if (expire_mode == 3) {
672 sprintf(buf, "%d", expire_value);
673 strprompt("Keep messages for how many days?", buf, 10);
674 expire_value = atol(buf);
678 printf("Save this configuration? ");
680 serv_puts("CONF set");
683 for (a=0; a<21; ++a) serv_puts(&sc[a][0]);
687 snprintf(buf, sizeof buf, "SPEX site|%d|%d",
688 expire_mode, expire_value);