1 /* Citadel/UX support routines */
10 #include <sys/types.h>
11 #include <sys/ioctl.h>
29 void set_keepalives();
34 #define IFAIDE if(axlevel>=6)
35 #define IFNAIDE if (axlevel<6)
37 extern unsigned userflags;
38 extern char *axdefs[7];
39 extern char sigcaught;
40 extern struct CtdlServInfo serv_info;
41 extern char rc_floor_mode;
43 int struncmp(lstr,rstr,len)
49 lc=tolower(lstr[pos]);
50 rc=tolower(rstr[pos]);
51 if ((lc==0)&&(rc==0)) return(0);
52 if (lc<rc) return(-1);
61 * check for the presence of a character within a string (returns count)
68 for (a=0; a<strlen(st); ++a) if (st[a]==ch) ++b;
74 * num_parms() - discover number of parameters...
81 for (a=0; a<strlen(source); ++a)
82 if (source[a]=='|') ++count;
87 * extract() - extract a parameter from a series of "|" separated...
89 void extract(dest,source,parmnum)
97 n = num_parms(source);
104 if ( (parmnum == 0) && (n == 1) ) {
109 while (count++ < parmnum) do {
111 } while( (strlen(buf)>0) && (buf[0]!='|') );
112 if (buf[0]=='|') strcpy(buf,&buf[1]);
113 for (count = 0; count<strlen(buf); ++count)
114 if (buf[count] == '|') buf[count] = 0;
119 * extract_int() - extract an int parm w/o supplying a buffer
121 int extract_int(source,parmnum)
126 extract(buf,source,parmnum);
131 * extract_long() - extract a long parm w/o supplying a buffer
133 long extract_long(source,parmnum)
138 extract(buf,source,parmnum);
142 void back(spaces) /* Destructive backspace */
145 for (a=1; a<=spaces; ++a) {
146 putc(8,stdout); putc(32,stdout); putc(8,stdout);
150 int yesno() { /* Returns 1 for yes, 0 for no */
153 a=inkey(); a=tolower(a);
154 if (a=='y') { printf("Yes\n"); return(1); }
155 if (a=='n') { printf("No\n"); return(0); }
159 int yesno_d(d) /* Returns 1 for yes, 0 for no, arg is default value */
163 a=inkey(); a=tolower(a);
164 if (a==13) a=(d ? 'y' : 'n');
165 if (a=='y') { printf("Yes\n"); return(1); }
166 if (a=='n') { printf("No\n"); return(0); }
171 void hit_any_key() { /* hit any key to continue */
174 printf("%s\r",serv_info.serv_moreprompt);
177 for (a=0; a<strlen(serv_info.serv_moreprompt); ++a)
181 if (b==NEXT_KEY) sigcaught = SIGINT;
182 if (b==STOP_KEY) sigcaught = SIGQUIT;
186 * change a user's access level
188 void edituser(userbuf)
189 struct usersupp *userbuf; {
193 newprompt("User name: ",who,25);
194 sprintf(buf,"QUSR %s",who);
198 printf("%s\n",&buf[4]);
206 int set_attr(sval,prompt,sbit)
215 printf("%45s [", prompt);
217 printf("%3s", ((temp&sbit) ? "Yes":"No"));
221 a=yesno_d(temp&sbit);
224 if (!a) temp=(temp^sbit);
229 * modes are: 0 - .EC command, 1 - .EC for new user,
230 * 2 - toggle Xpert mode 3 - toggle floor mode
232 void enter_config(mode)
234 int width,height,flags;
241 printf("%s\n",&buf[4]);
245 width = extract_int(&buf[4],0);
246 height = extract_int(&buf[4],1);
247 flags = extract_int(&buf[4],2);
249 if ((mode==0)||(mode==1)) {
251 width = intprompt("Enter your screen width",width,20,255);
252 height = intprompt("Enter your screen height",height,3,255);
254 flags = set_attr(flags,
255 "Are you an experienced Citadel user",US_EXPERT);
256 if ( ((flags&US_EXPERT)==0) && (mode==1))
258 flags = set_attr(flags,
259 "Print last old message on New message request",US_LASTOLD);
260 if ((flags&US_EXPERT)==0) formout("unlisted");
261 flags = set_attr(flags,"Be unlisted in userlog",US_UNLISTED);
262 flags = set_attr(flags,"Suppress message prompts",US_NOPROMPT);
263 if ((flags & US_NOPROMPT)==0)
264 flags = set_attr(flags,"Use 'disappearing' prompts",US_DISAPPEAR);
265 flags = set_attr(flags,
266 "Pause after each screenful of text",US_PAGINATOR);
267 if (rc_floor_mode == RC_DEFAULT) {
268 flags = set_attr(flags,
269 "View rooms by floor",US_FLOORS);
274 if (flags & US_EXPERT) {
275 flags = (flags ^ US_EXPERT);
276 printf("Expert mode now OFF\n");
279 flags = (flags | US_EXPERT);
280 printf("Expert mode now ON\n");
285 if (flags & US_FLOORS) {
286 flags = (flags ^ US_FLOORS);
287 printf("Floor mode now OFF\n");
290 flags = (flags | US_FLOORS);
291 printf("Floor mode now ON\n");
295 sprintf(buf,"SETU %d|%d|%d",width,height,flags);
298 if (buf[0]!='2') printf("%s\n",&buf[4]);
303 * getstring() - get a line of text from a file
304 * ignores lines beginning with "#"
306 int getstring(fp,string)
322 } while(string[0]=='#');
323 return(strlen(string));
326 int pattern(search,patn) /* Searches for patn in search string */
331 for (a=0; a<strlen(search); ++a)
332 { b=struncmp(&search[a],patn,strlen(patn));
338 void interr(errnum) /* display internal error as defined in errmsgs */
340 printf("*** INTERNAL ERROR %d\n",errnum);
341 printf("(Press any key to continue)\n");
349 * Check to see if we need to pause at the end of a screen.
350 * If we do, we have to disable server keepalives during the pause because
351 * we are probably in the middle of a server operation and the NOOP command
352 * would confuse everything.
354 int checkpagin(lp,pagin,height)
357 if (pagin!=1) return(0);
358 if (lp>=(height-1)) {
359 set_keepalives(KA_NO);
361 set_keepalives(KA_YES);
373 if (strlen(string)==0) return;
375 /* Convert non-printable characters to blanks */
376 for (a=0; a<strlen(string); ++a) {
377 if (string[a]<32) string[a]=32;
378 if (string[a]>126) string[a]=32;
381 /* Remove leading and trailing blanks */
382 while(string[0]<33) strcpy(string,&string[1]);
383 while(string[strlen(string)-1]<33) string[strlen(string)-1]=0;
385 /* Remove double blanks */
386 for (a=0; a<strlen(string); ++a) {
387 if ((string[a]==32)&&(string[a+1]==32)) {
388 strcpy(&string[a],&string[a+1]);
393 /* remove characters which would interfere with the network */
394 for (a=0; a<strlen(string); ++a) {
395 if (string[a]=='!') strcpy(&string[a],&string[a+1]);
396 if (string[a]=='@') strcpy(&string[a],&string[a+1]);
397 if (string[a]=='_') strcpy(&string[a],&string[a+1]);
398 if (string[a]==',') strcpy(&string[a],&string[a+1]);
399 if (string[a]=='%') strcpy(&string[a],&string[a+1]);
400 if (string[a]=='|') strcpy(&string[a],&string[a+1]);
411 for (i=0; i<strlen(str); ++i) h=h+((i+1)*tolower(str[i]));
415 long finduser(file,name)
423 fp=fopen("hashtab","r");
424 while(fread((char *)&fh,sizeof(int),1,fp)>0) {
429 pp = pp + (long)sizeof(struct usersupp);
436 int alias(name) /* process alias and routing info for mail */
440 char aaa[300],bbb[300];
442 fp=fopen("network/mail.aliases","r");
443 if (fp==NULL) return(2);
444 GNA: strcpy(aaa,""); strcpy(bbb,"");
448 if (a>0) { b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
453 if (a>0) { b=strlen(bbb); bbb[b]=a; bbb[b+1]=0; }
459 if (strucmp(name,aaa)) goto GNA;
462 printf("*** Mail is being forwarded to %s\n",name);
464 DETYPE: /* determine local or remote type, see citadel.h */
465 for (a=0; a<strlen(name); ++a) if (name[a]=='!') return(M_INTERNET);
466 for (a=0; a<strlen(name); ++a)
468 for (b=a; b<strlen(name); ++b)
469 if (name[b]=='.') return(M_INTERNET);
470 b=0; for (a=0; a<strlen(name); ++a) if (name[a]=='@') ++b;
472 printf("Too many @'s in address\n");
476 for (a=0; a<strlen(name); ++a)
477 if (name[a]=='@') strcpy(bbb,&name[a+1]);
478 while (bbb[0]==32) strcpy(bbb,&bbb[1]);
479 fp = fopen("network/mail.sysinfo","r");
480 if (fp==NULL) return(M_ERROR);
483 } while ((a>=0)&&(strucmp(aaa,bbb)));
485 if (!strncmp(aaa,"use ",4)) {
491 if (!strncmp(aaa,"uum",3)) {
493 for (a=0; a<strlen(bbb); ++a) {
494 if (bbb[a]=='@') bbb[a]=0;
495 if (bbb[a]==' ') bbb[a]='_';
497 while(bbb[strlen(bbb)-1]=='_') bbb[strlen(bbb)-1]=0;
498 sprintf(name,&aaa[4],bbb);
501 if (!strncmp(aaa,"bin",3)) {
502 strcpy(aaa,name); strcpy(bbb,name);
503 while (aaa[strlen(aaa)-1]!='@') aaa[strlen(aaa)-1]=0;
504 aaa[strlen(aaa)-1]=0;
505 while (aaa[strlen(aaa)-1]==' ') aaa[strlen(aaa)-1]=0;
506 while (bbb[0]!='@') strcpy(bbb,&bbb[1]);
508 while (bbb[0]==' ') strcpy(bbb,&bbb[1]);
509 sprintf(name,"%s @%s",aaa,bbb);
520 * replacement strerror() for systems that don't have it
526 sprintf(buf,"errno = %d",e);
532 void progress(curr,cmax)
535 static long dots_printed;
539 printf(".......................................");
540 printf(".......................................\r");
544 else if (curr==cmax) {
545 printf("\r%79s\n","");
548 a=(curr * 100) / cmax;
550 while (dots_printed < a) {
560 * NOT the same locate_host() in locate_host.c. This one just does a
561 * 'who am i' to try to discover where the user is...
563 void locate_host(hbuf)
569 who = (FILE *)popen("who am i","r");
571 strcpy(hbuf,serv_info.serv_fqdn);
578 for (a=0; a<strlen(buf); ++a) {
579 if ((buf[a]=='(')||(buf[a]==')')) ++b;
582 strcpy(hbuf,serv_info.serv_fqdn);
586 for (a=0; a<strlen(buf); ++a) {
588 strcpy(buf,&buf[a+1]);
591 for (a=0; a<strlen(buf); ++a) {
592 if (buf[a]==')') buf[a] = 0;
595 if (strlen(buf)==0) strcpy(hbuf,serv_info.serv_fqdn);
596 else strncpy(hbuf,buf,24);
600 * miscellaneous server commands (testing, etc.)
602 void misc_server_cmd(char *cmd) {
609 while (serv_gets(buf), strcmp(buf,"000")) {
616 newprompt("> ",buf,255);
618 } while(strcmp(buf,"000"));
625 * compute the checksum of a file
627 int file_checksum(filename)
633 fp = fopen(filename,"r");
634 if (fp == NULL) return(0);
636 /* yes, this algorithm may allow cksum to overflow, but that's ok
637 * as long as it overflows consistently, which it will.
639 while (ch=getc(fp), ch>=0) {
640 cksum = (cksum + ch);
648 * nuke a directory and its contents
656 dp = opendir(dirname);
661 while (d = readdir(dp), d != NULL) {
662 sprintf(filename, "%s/%s", dirname, d->d_name);
667 return(rmdir(dirname));