1 /* More Citadel/UX routines...
2 * unlike routines.c, some of these DO use global variables.
19 #include "routines2.h"
21 void interr(int errnum);
22 void strprompt(char *prompt, char *str, int len);
23 void newprompt(char *prompt, char *str, int len);
24 void sttybbs(int cmd);
26 int ka_wait(pid_t *kstatus);
27 void serv_write(char *buf, int nbytes);
28 void extract(char *dest, char *source, int parmnum);
29 int haschar(char *st, int ch);
30 void progress(long int curr, long int cmax);
31 void citedit(FILE *fp, long int base_pos);
33 void nukedir(char *dirname);
36 extern char tempdir[];
37 extern char *axdefs[7];
38 extern long highest_msg_read;
39 extern long maxmsgnum;
40 extern unsigned room_flags;
41 extern int screenwidth;
44 int eopen(char *name, int mode)
47 ret = open(name,mode);
49 fprintf(stderr,"Cannot open file '%s', mode=%d, errno=%d\n",
57 int room_prompt(int qrflags) /* return proper room prompt character */
61 if (qrflags&QR_DIRECTORY) a=']';
62 if ((a==']')&&(qrflags&QR_NETWORK)) a='}';
63 if ((a=='>')&&(qrflags&QR_NETWORK)) a=')';
67 void entregis(void) /* register with name and address */
88 serv_puts("GREG _SELF_");
92 while (serv_gets(buf), strcmp(buf,"000")) {
93 if (a==2) strcpy(tmpname,buf);
94 if (a==3) strcpy(tmpaddr,buf);
95 if (a==4) strcpy(tmpcity,buf);
96 if (a==5) strcpy(tmpstate,buf);
97 if (a==6) strcpy(tmpzip,buf);
98 if (a==7) strcpy(tmpphone,buf);
99 if (a==9) strcpy(tmpemail,buf);
104 strprompt("REAL name",tmpname,29);
105 strprompt("Address",tmpaddr,24);
106 strprompt("City/town",tmpcity,14);
107 strprompt("State",tmpstate,2);
108 strprompt("ZIP Code",tmpzip,10);
109 strprompt("Telephone number",tmpphone,14);
110 strprompt("Email address",tmpemail,31);
112 /* now send the registration info back to the server */
116 printf("%s\n",&buf[4]);
130 void updatels(void) { /* make all messages old in current room */
132 serv_puts("SLRP HIGHEST");
134 if (buf[0]!='2') printf("%s\n",&buf[4]);
137 void updatelsa(void) { /* only make messages old in this room that have been read */
139 sprintf(buf,"SLRP %ld",highest_msg_read);
142 if (buf[0]!='2') printf("%s\n",&buf[4]);
147 * This routine completes a client upload
149 void do_upload(int fd) {
152 long transmitted_bytes, total_bytes;
156 /* learn the size of the file */
157 total_bytes = lseek(fd,0L,2);
160 transmitted_bytes = 0L;
161 progress(transmitted_bytes,total_bytes);
163 bytes_to_send = read(fd,tbuf,4096);
164 if (bytes_to_send>0) {
165 sprintf(buf,"WRIT %d",bytes_to_send);
169 bytes_expected = atoi(&buf[4]);
170 serv_write(tbuf,bytes_expected);
173 printf("%s\n",&buf[4]);
176 transmitted_bytes = transmitted_bytes + (long)bytes_to_send;
177 progress(transmitted_bytes, total_bytes);
178 } while (bytes_to_send > 0);
180 /* close the upload file, locally and at the server */
184 printf("%s\n",&buf[4]);
189 * client-based uploads (for users with their own clientware)
191 void cli_upload(void) {
199 if ((room_flags & QR_UPLOAD) == 0) {
200 printf("*** You cannot upload to this room.\n");
204 newprompt("File to be uploaded: ",flnm,55);
205 fd = open(flnm,O_RDONLY);
207 printf("Cannot open '%s': %s\n",flnm,strerror(errno));
210 printf("Enter a description of this file:\n");
211 newprompt(": ",desc,75);
213 /* keep generating filenames in hope of finding a unique one */
216 if (a==10) return; /* fail if tried 10 times */
218 while ((strlen(buf)>0)&&(haschar(buf,'/')))
220 if (a>0) sprintf(&buf[strlen(buf)],"%d",a);
221 sprintf(tbuf,"UOPN %s|%s",buf,desc);
224 if (buf[0]!='2') printf("%s\n",&buf[4]);
226 } while (buf[0]!='2');
228 /* at this point we have an open upload file at the server */
234 * Function used for various image upload commands
236 void cli_image_upload(char *keyname) {
241 sprintf(buf, "UIMG 0|%s", keyname);
245 printf("%s\n", &buf[4]);
249 newprompt("Image file to be uploaded: ",flnm,55);
250 fd = open(flnm,O_RDONLY);
252 printf("Cannot open '%s': %s\n",flnm,strerror(errno));
256 sprintf(buf, "UIMG 1|%s", keyname);
260 printf("%s\n", &buf[4]);
269 * protocol-based uploads (Xmodem, Ymodem, Zmodem)
271 void upload(int c) /* c = upload mode */
282 if ((room_flags & QR_UPLOAD) == 0) {
283 printf("*** You cannot upload to this room.\n");
287 /* we don't need a filename when receiving batch y/z modem */
288 if ((c==2)||(c==3)) strcpy(flnm,"x");
289 else newprompt("Enter filename: ",flnm,15);
291 for (a=0; a<strlen(flnm); ++a)
292 if ( (flnm[a]=='/') || (flnm[a]=='\\') || (flnm[a]=='>')
293 || (flnm[a]=='?') || (flnm[a]=='*')
294 || (flnm[a]==';') || (flnm[a]=='&') ) flnm[a]='_';
296 newprompt("Enter a short description of the file:\n: ",desc,150);
298 /* create a temporary directory... */
299 if (mkdir(tempdir,0700) != 0) {
300 printf("*** Could not create temporary directory %s: %s\n",
301 tempdir,strerror(errno));
305 /* now do the transfer ... in a separate process */
312 printf("Receiving %s - press Ctrl-D to end.\n",flnm);
313 fp = fopen(flnm,"w");
328 execlp("rx","rx",flnm,NULL);
332 execlp("rb","rb",NULL);
336 execlp("rz","rz",NULL);
342 } while ((b!=xfer_pid)&&(b!=(-1)));
346 printf("\r*** Transfer unsuccessful.\n");
351 printf("\r*** Transfer successful. Sending file(s) to server...\n");
352 sprintf(buf,"cd %s; ls",tempdir);
353 lsfp = popen(buf,"r");
355 while (fgets(flnm,256,lsfp)!=NULL) {
356 flnm[strlen(flnm)-1] = 0;
357 sprintf(buf,"%s/%s",tempdir,flnm);
358 fd = open(buf,O_RDONLY);
362 sprintf(buf,"UOPN %s|%s",flnm,desc);
363 if (a>0) sprintf(&buf[strlen(buf)],
368 } while((buf[0]!='2')&&(a<100));
369 if (buf[0]=='2') do {
370 a=read(fd,tbuf,4096);
372 sprintf(buf,"WRIT %d",a);
382 printf("%s\n",&buf[4]);
394 void val_user(char *user)
401 sprintf(cmd,"GREG %s",user);
409 if (a==1) printf("User #%s - %s ",
411 if (a==2) printf("PW: %s\n",buf);
412 if (a==3) printf("%s\n",buf);
413 if (a==4) printf("%s\n",buf);
414 if (a==5) printf("%s, ",buf);
415 if (a==6) printf("%s ",buf);
416 if (a==7) printf("%s\n",buf);
417 if (a==8) printf("%s\n",buf);
418 if (a==9) ax=atoi(buf);
419 if (a==10) printf("%s\n",buf);
420 } while(strcmp(buf,"000"));
421 printf("Current access level: %d (%s)\n",ax,axdefs[ax]);
424 printf("%-30s\n%s\n",user,&cmd[4]);
427 /* now set the access level */
429 printf("Access level (? for list): ");
434 printf("%d %s\n",b,axdefs[b]);
437 } while((a<0)||(a>6));
439 sprintf(cmd,"VALI %s|%d",user,a);
442 if (cmd[0]!='2') printf("%s\n",&cmd[4]);
447 void validate(void) { /* validate new users */
455 if (cmd[0]!='3') finished = 1;
456 if (cmd[0]=='2') printf("%s\n",&cmd[4]);
461 } while(finished==0);
464 void subshell(void) {
469 signal(SIGINT,SIG_DFL);
470 signal(SIGQUIT,SIG_DFL);
471 execlp(getenv("SHELL"),getenv("SHELL"),NULL);
472 printf("Could not open a shell: %s\n", strerror(errno));
477 } while ((a!=b)&&(a!=(-1)));
482 * <.A>ide <F>ile <D>elete command
484 void deletefile(void) {
488 newprompt("Filename: ",filename,31);
489 if (strlen(filename)==0) return;
490 sprintf(cmd,"DELF %s",filename);
493 printf("%s\n",&cmd[4]);
497 * <.A>ide <F>ile <S>end command
499 void netsendfile(void) {
500 char filename[32],destsys[20],cmd[256];
502 newprompt("Filename: ",filename,31);
503 if (strlen(filename)==0) return;
504 newprompt("System to send to: ",destsys,19);
505 sprintf(cmd,"NETF %s|%s",filename,destsys);
508 printf("%s\n",&cmd[4]);
513 * <.A>ide <F>ile <M>ove command
515 void movefile(void) {
520 newprompt("Filename: ",filename,63);
521 if (strlen(filename)==0) return;
522 newprompt("Enter target room: ",newroom,19);
524 sprintf(cmd,"MOVF %s|%s",filename,newroom);
527 printf("%s\n",&cmd[4]);
532 * list of users who have filled out a bio
534 void list_bio(void) {
541 printf("%s\n",&buf[4]);
544 while (serv_gets(buf), strcmp(buf,"000")) {
545 if ((pos+strlen(buf)+5)>screenwidth) {
550 pos = pos + strlen(buf) + 2;
552 printf("%c%c \n\n",8,8);
559 void read_bio(void) {
564 newprompt("Read bio for who ('?' for list) : ",who,25);
566 if (!strcmp(who,"?")) list_bio();
567 } while(!strcmp(who,"?"));
568 sprintf(buf,"RBIO %s",who);
572 printf("%s\n",&buf[4]);
575 while (serv_gets(buf), strcmp(buf,"000")) {