|
|
1.1 root 1: #line 1 "CON_HI.C"
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "sbbs.h"
6:
7: extern char question[128];
8:
9: char *mnestr;
10:
11: /****************************************************************************/
12: /* Waits for remote or local user to input a CR terminated string. 'length' */
13: /* is the maximum number of characters that getstr will allow the user to */
14: /* input into the string. 'mode' specifies upper case characters are echoed */
15: /* or wordwrap or if in message input (^A sequences allowed). ^W backspaces */
16: /* a word, ^X backspaces a line, ^Gs, BSs, TABs are processed, LFs ignored. */
17: /* ^N non-destructive BS, ^V center line. Valid keys are echoed. */
18: /****************************************************************************/
19: int getstr(char *strout, int maxlen, long mode)
20: {
21: int i,l,x,z; /* i=current position, l=length, j=printed chars */
22: /* x&z=misc */
23: uchar ch,str1[256],str2[256],ins=0,atr;
24:
25: console&=~CON_UPARROW;
26: sys_status&=~SS_ABORT;
27: if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) {
28: attr(color[clr_inputline]);
29: for(i=0;i<maxlen;i++)
30: outchar(SP);
31: bprintf("\x1b[%dD",maxlen); }
32: if(wordwrap[0]) {
33: strcpy(str1,wordwrap);
34: wordwrap[0]=0; }
35: else str1[0]=0;
36: if(mode&K_EDIT)
37: strcat(str1,strout);
38: if(strlen(str1)>maxlen)
39: str1[maxlen]=0;
40: atr=curatr;
41: if(!(mode&K_NOECHO)) {
42: if(mode&K_AUTODEL && str1[0]) {
43: i=(color[clr_inputline]&0x77)<<4;
44: i|=(color[clr_inputline]&0x77)>>4;
45: attr(i); }
46: rputs(str1);
47: if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI)
48: bputs("\x1b[K"); /* destroy to eol */ }
49:
50: i=l=strlen(str1);
51: if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) {
52: ch=getkey(mode|K_GETSTR);
53: attr(atr);
54: if(isprint(ch) || ch==0x7f) {
55: for(i=0;i<l;i++)
56: bputs("\b \b");
57: i=l=0; }
58: else {
59: for(i=0;i<l;i++)
60: outchar(BS);
61: rputs(str1);
62: i=l; }
63: if(ch!=SP && ch!=TAB)
64: ungetkey(ch); }
65:
66: while(!(sys_status&SS_ABORT) && (ch=getkey(mode|K_GETSTR))!=CR && online) {
67: if(sys_status&SS_ABORT)
68: break;
69: if(ch==LF) /* Ctrl-J same as CR */
70: break;
1.1.1.2 ! root 71: if(ch==TAB && !(mode&K_WRAP)) /* TAB same as CR */
! 72: break;
1.1 root 73: if(!i && mode&K_UPRLWR && (ch==SP || ch==TAB))
74: continue; /* ignore beginning white space if upper/lower */
75: if(mode&K_E71DETECT && ch==(CR|0x80) && l>1) {
76: if(strstr(str1,"��")) {
77: bputs("\r\n\r\nYou must set your terminal to NO PARITY, "
78: "8 DATA BITS, and 1 STOP BIT (N-8-1).\7\r\n");
79: return(0); } }
80: switch(ch) {
81: case 1: /* Ctrl-A for ANSI */
82: if(!(mode&K_MSG) || useron.rest&FLAG('A') || i>maxlen-3)
83: break;
84: if(ins) {
85: if(l<maxlen)
86: l++;
87: for(x=l;x>i;x--)
88: str1[x]=str1[x-1];
89: rprintf("%.*s",l-i,str1+i);
90: rprintf("\x1b[%dD",l-i);
91: if(i==maxlen-1)
92: ins=0; }
93: outchar(str1[i++]=1);
94: break;
95: case 2: /* Ctrl-B Beginning of Line */
96: if(useron.misc&ANSI && i && !(mode&K_NOECHO)) {
97: bprintf("\x1b[%dD",i);
98: i=0; }
99: break;
100: case 4: /* Ctrl-D Delete word right */
101: if(i<l) {
102: x=i;
103: while(x<l && str1[x]!=SP) {
104: outchar(SP);
105: x++; }
106: while(x<l && str1[x]==SP) {
107: outchar(SP);
108: x++; }
109: bprintf("\x1b[%dD",x-i); /* move cursor back */
110: z=i;
111: while(z<l-(x-i)) { /* move chars in string */
112: outchar(str1[z]=str1[z+(x-i)]);
113: z++; }
114: while(z<l) { /* write over extra chars */
115: outchar(SP);
116: z++; }
117: bprintf("\x1b[%dD",z-i);
118: l-=x-i; } /* l=new length */
119: break;
120: case 5: /* Ctrl-E End of line */
121: if(useron.misc&ANSI && i<l) {
122: bprintf("\x1b[%dC",l-i); /* move cursor to eol */
123: i=l; }
124: break;
125: case 6: /* Ctrl-F move cursor forewards */
126: if(i<l && (useron.misc&ANSI)) {
127: bputs("\x1b[C"); /* move cursor right one */
128: i++; }
129: break;
130: case 7:
131: if(!(mode&K_MSG))
132: break;
133: if(useron.rest&FLAG('B')) {
134: if (i+6<maxlen) {
135: if(ins) {
136: for(x=l+6;x>i;x--)
137: str1[x]=str1[x-6];
138: if(l+5<maxlen)
139: l+=6;
140: if(i==maxlen-1)
141: ins=0; }
142: str1[i++]='(';
143: str1[i++]='b';
144: str1[i++]='e';
145: str1[i++]='e';
146: str1[i++]='p';
147: str1[i++]=')';
148: if(!(mode&K_NOECHO))
149: bputs("(beep)"); }
150: if(ins)
151: redrwstr(str1,i,l,0);
152: break; }
153: if(ins) {
154: if(l<maxlen)
155: l++;
156: for(x=l;x>i;x--)
157: str1[x]=str1[x-1];
158: if(i==maxlen-1)
159: ins=0; }
160: if(i<maxlen) {
161: str1[i++]=7;
162: if(!(mode&K_NOECHO))
163: outchar(7); }
164: break;
165: case 14: /* Ctrl-N Next word */
166: if(i<l && (useron.misc&ANSI)) {
167: x=i;
168: while(str1[i]!=SP && i<l)
169: i++;
170: while(str1[i]==SP && i<l)
171: i++;
172: bprintf("\x1b[%dC",i-x); }
173: break;
174: case 0x1c: /* Ctrl-\ Previous word */
175: if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
176: x=i;
177: while(str1[i-1]==SP && i)
178: i--;
179: while(str1[i-1]!=SP && i)
180: i--;
181: bprintf("\x1b[%dD",x-i); }
182: break;
183: case 18: /* Ctrl-R Redraw Line */
184: if(!(mode&K_NOECHO))
185: redrwstr(str1,i,l,0);
186: break;
187: case TAB:
188: if(!(i%TABSIZE)) {
189: if(ins) {
190: if(l<maxlen)
191: l++;
192: for(x=l;x>i;x--)
193: str1[x]=str1[x-1];
194: if(i==maxlen-1)
195: ins=0; }
196: str1[i++]=SP;
197: if(!(mode&K_NOECHO))
198: outchar(SP); }
199: while(i<maxlen && i%TABSIZE) {
200: if(ins) {
201: if(l<maxlen)
202: l++;
203: for(x=l;x>i;x--)
204: str1[x]=str1[x-1];
205: if(i==maxlen-1)
206: ins=0; }
207: str1[i++]=SP;
208: if(!(mode&K_NOECHO))
209: outchar(SP); }
210: if(ins && !(mode&K_NOECHO))
211: redrwstr(str1,i,l,0);
212: break;
213: case BS:
214: if(!i)
215: break;
216: i--;
217: l--;
218: if(i!=l) { /* Deleting char in middle of line */
219: outchar(BS);
220: z=i;
221: while(z<l) { /* move the characters in the line */
222: outchar(str1[z]=str1[z+1]);
223: z++; }
224: outchar(SP); /* write over the last char */
225: bprintf("\x1b[%dD",(l-i)+1); }
226: else if(!(mode&K_NOECHO))
227: bputs("\b \b");
228: break;
229: case 22: /* Ctrl-V Center line */
230: str1[l]=0;
231: l=bstrlen(str1);
232: if(!l) break;
233: for(x=0;x<(maxlen-l)/2;x++)
234: str2[x]=SP;
235: str2[x]=0;
236: strcat(str2,str1);
237: strcpy(strout,str2);
238: l=strlen(strout);
239: if(mode&K_NOECHO)
240: return(l);
241: if(mode&K_MSG)
242: redrwstr(strout,i,l,K_MSG);
243: else {
244: while(i--)
245: bputs("\b");
246: bputs(strout);
247: if(mode&K_LINE)
248: attr(LIGHTGRAY); }
249: CRLF;
250: return(l);
251: case 23: /* Ctrl-W Delete word left */
252: if(i<l) {
253: x=i; /* x=original offset */
254: while(i && str1[i-1]==SP) {
255: outchar(BS);
256: i--; }
257: while(i && str1[i-1]!=SP) {
258: outchar(BS);
259: i--; }
260: z=i; /* i=z=new offset */
261: while(z<l-(x-i)) { /* move chars in string */
262: outchar(str1[z]=str1[z+(x-i)]);
263: z++; }
264: while(z<l) { /* write over extra chars */
265: outchar(SP);
266: z++; }
267: bprintf("\x1b[%dD",z-i); /* back to new x corridnant */
268: l-=x-i; } /* l=new length */
269: else {
270: while(i && str1[i-1]==SP) {
271: i--;
272: l--;
273: if(!(mode&K_NOECHO))
274: bputs("\b \b"); }
275: while(i && str1[i-1]!=SP) {
276: i--;
277: l--;
278: if(!(mode&K_NOECHO))
279: bputs("\b \b"); } }
280: break;
281: case 24: /* Ctrl-X Delete entire line */
282: if(mode&K_NOECHO)
283: l=0;
284: else {
285: while(i<l) {
286: outchar(SP);
287: i++; }
288: while(l) {
289: l--;
290: bputs("\b \b"); } }
291: i=0;
292: break;
293: case 25: /* Ctrl-Y Delete to end of line */
294: if(useron.misc&ANSI && !(mode&K_NOECHO)) {
295: bputs("\x1b[K");
296: l=i; }
297: break;
298: case 31: /* Ctrl-Minus Toggles Insert/Overwrite */
299: if(!(useron.misc&ANSI) || mode&K_NOECHO)
300: break;
301: if(ins) {
302: ins=0;
303: redrwstr(str1,i,l,0); }
304: else if(i<l) {
305: ins=1;
306: bprintf("\x1b[s\x1b[%dC",79-lclwx()); /* save pos */
307: z=curatr; /* and got to EOL */
308: attr(z|BLINK|HIGH);
309: outchar('�');
310: attr(z);
311: bputs("\x1b[u"); } /* restore pos */
312: break;
313: case 0x1e: /* Ctrl-^ */
314: if(!(mode&K_EDIT))
315: break;
316: if(i>l)
317: l=i;
318: str1[l]=0;
319: strcpy(strout,str1);
320: if((stripattr(strout) || ins) && !(mode&K_NOECHO))
321: redrwstr(strout,i,l,K_MSG);
322: if(mode&K_LINE && !(mode&K_NOECHO))
323: attr(LIGHTGRAY);
324: console|=CON_UPARROW;
325: return(l);
326: case 0x1d: /* Ctrl-] Reverse Cursor Movement */
327: if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
328: bputs("\x1b[D"); /* move cursor left one */
329: i--; }
330: break;
331: case 0x7f: /* Ctrl-BkSpc (DEL) Delete current char */
332: if(i==l)
333: break;
334: l--;
335: z=i;
336: while(z<l) { /* move the characters in the line */
337: outchar(str1[z]=str1[z+1]);
338: z++; }
339: outchar(SP); /* write over the last char */
340: bprintf("\x1b[%dD",(l-i)+1);
341: break;
342: default:
343: if(mode&K_WRAP && i==maxlen && ch>=SP && !ins) {
344: str1[i]=0;
345: if(ch==SP && !(mode&K_CHAT)) { /* don't wrap a space */
346: strcpy(strout,str1); /* as last char */
347: if(stripattr(strout) && !(mode&K_NOECHO))
348: redrwstr(strout,i,l,K_MSG);
349: if(!(mode&K_NOECHO))
350: CRLF;
351: return(i); }
352: x=i-1;
353: z=1;
354: wordwrap[0]=ch;
355: while(str1[x]!=SP && x)
356: wordwrap[z++]=str1[x--];
357: if(x<(maxlen/2)) {
358: wordwrap[1]=0; /* only wrap one character */
359: strcpy(strout,str1);
360: if(stripattr(strout) && !(mode&K_NOECHO))
361: redrwstr(strout,i,l,K_MSG);
362: if(!(mode&K_NOECHO))
363: CRLF;
364: return(i); }
365: wordwrap[z]=0;
366: if(!(mode&K_NOECHO))
367: while(z--) {
368: bputs("\b \b");
369: i--; }
370: strrev(wordwrap);
371: str1[x]=0;
372: strcpy(strout,str1);
373: if(stripattr(strout) && !(mode&K_NOECHO))
374: redrwstr(strout,i,x,mode);
375: if(!(mode&K_NOECHO))
376: CRLF;
377: return(x); }
378: if(i<maxlen && ch>=SP) {
379: if(mode&K_UPRLWR)
380: if(!i || (i && (str1[i-1]==SP || str1[i-1]=='-'
381: || str1[i-1]=='.' || str1[i-1]=='_')))
382: ch=toupper(ch);
383: else
384: ch=tolower(ch);
385: if(ins) {
386: if(l<maxlen) /* l<maxlen */
387: l++;
388: for(x=l;x>i;x--)
389: str1[x]=str1[x-1];
390: rprintf("%.*s",l-i,str1+i);
391: rprintf("\x1b[%dD",l-i);
392: if(i==maxlen-1) {
393: bputs(" \b\b");
394: ins=0; } }
395: str1[i++]=ch;
396: if(!(mode&K_NOECHO))
397: outchar(ch); } }
398: if(i>l)
399: l=i;
400: if(mode&K_CHAT && !l)
401: return(0); }
402: if(!online)
403: return(0);
404: if(i>l)
405: l=i;
406: str1[l]=0;
407: if(!(sys_status&SS_ABORT)) {
408: strcpy(strout,str1);
409: if((stripattr(strout) || ins) && !(mode&K_NOECHO))
410: redrwstr(strout,i,l,K_MSG); }
411: else
412: l=0;
413: if(mode&K_LINE && !(mode&K_NOECHO)) attr(LIGHTGRAY);
414: if(!(mode&(K_NOCRLF|K_NOECHO))) {
415: outchar(CR);
416: if(!(mode&K_MSG && sys_status&SS_ABORT))
417: outchar(LF);
418: lncntr=0; }
419: return(l);
420: }
421:
422: /****************************************************************************/
423: /* Hot keyed number input routine. */
424: /* Returns a valid number between 1 and max, 0 if no number entered, or -1 */
425: /* if the user hit 'Q' or ctrl-c */
426: /****************************************************************************/
427: long getnum(ulong max)
428: {
429: uchar ch,n=0;
430: long i=0;
431:
432: while(online) {
433: ch=getkey(K_UPPER);
434: if(ch>0x7f)
435: continue;
436: if(ch=='Q') {
437: outchar('Q');
438: if(useron.misc&COLDKEYS)
439: ch=getkey(K_UPPER);
440: if(ch==BS) {
441: bputs("\b \b");
442: continue; }
443: CRLF;
444: lncntr=0;
445: return(-1); }
446: else if(sys_status&SS_ABORT) {
447: CRLF;
448: lncntr=0;
449: return(-1); }
450: else if(ch==CR) {
451: CRLF;
452: lncntr=0;
453: return(i); }
454: else if(ch==BS && n) {
455: bputs("\b \b");
456: i/=10;
457: n--; }
458: else if(isdigit(ch) && (i*10L)+(ch&0xf)<=max && (ch!='0' || n)) {
459: i*=10L;
460: n++;
461: i+=ch&0xf;
462: outchar(ch);
463: if(i*10L>max && !(useron.misc&COLDKEYS)) {
464: CRLF;
465: lncntr=0;
466: return(i); } } }
467: return(0);
468: }
469:
470: /*****************************************************************************/
471: /* Displays or erases [WAIT] message */
472: /*****************************************************************************/
473: void waitforsysop(char on)
474: {
475: static saveatr;
476: int i,j;
477:
478: if(on) {
479: saveatr=curatr;
480: bputs(text[Wait]);
481: lclatr(LIGHTGRAY);
482: return; }
483: j=bstrlen(text[Wait]);
484: attr(saveatr);
485: for(i=0;i<j;i++)
486: bputs("\b \b");
487: }
488:
489: /****************************************************************************/
490: /* Returns 1 if a is a valid ctrl-a code, 0 if it isn't. */
491: /****************************************************************************/
492: char validattr(char a)
493: {
494:
495: switch(toupper(a)) {
496: case '-': /* clear */
497: case '_': /* clear */
498: case 'B': /* blue fg */
499: case 'C': /* cyan fg */
500: case 'G': /* green fg */
501: case 'H': /* high fg */
502: case 'I': /* blink */
503: case 'K': /* black fg */
504: case 'L': /* cls */
505: case 'M': /* magenta fg */
506: case 'N': /* normal */
507: case 'P': /* pause */
508: case 'R': /* red fg */
509: case 'W': /* white fg */
510: case 'Y': /* yellow fg */
511: case '0': /* black bg */
512: case '1': /* red bg */
513: case '2': /* green bg */
514: case '3': /* brown bg */
515: case '4': /* blue bg */
516: case '5': /* magenta bg */
517: case '6': /* cyan bg */
518: case '7': /* white bg */
519: return(1); }
520: return(0);
521: }
522:
523: /****************************************************************************/
524: /* Strips invalid Ctrl-Ax sequences from str */
525: /* Returns number of ^A's in line */
526: /****************************************************************************/
527: char stripattr(char *strin)
528: {
529: uchar str[256];
530: uchar a,c,d,e;
531:
532: e=strlen(strin);
533: for(a=c=d=0;c<e;c++) {
534: if(strin[c]==1) {
535: a++;
536: if(!validattr(strin[c+1])) {
537: c++;
538: continue; } }
539: str[d++]=strin[c]; }
540: str[d]=0;
541: strcpy(strin,str);
542: return(a);
543: }
544:
545: /****************************************************************************/
546: /* Redraws str using i as current cursor position and l as length */
547: /****************************************************************************/
548: void redrwstr(char *strin, int i, int l, char mode)
549: {
550: char str[256],c;
551:
552: sprintf(str,"%-*.*s",l,l,strin);
553: c=i;
554: while(c--)
555: outchar(BS);
556: if(mode&K_MSG)
557: bputs(str);
558: else
559: rputs(str);
560: if(useron.misc&ANSI) {
561: bputs("\x1b[K");
562: if(i<l)
563: bprintf("\x1b[%dD",l-i); }
564: else {
565: while(c<79) { /* clear to end of line */
566: outchar(SP);
567: c++; }
568: while(c>l) { /* back space to end of string */
569: outchar(BS);
570: c--; } }
571: }
572:
573: /****************************************************************************/
574: /* Outputs a string highlighting characters preceeded by a tilde */
575: /****************************************************************************/
576: void mnemonics(char *str)
577: {
578: char *ctrl_a_codes;
579: long l;
580:
581: if(!strchr(str,'~')) {
582: mnestr=str;
583: bputs(str);
584: return; }
585: ctrl_a_codes=strchr(str,1);
586: if(!ctrl_a_codes) {
587: if(str[0]=='@' && str[strlen(str)-1]=='@' && !strchr(str,SP)) {
588: mnestr=str;
589: bputs(str);
590: return; }
591: attr(color[clr_mnelow]); }
592: l=0L;
593: while(str[l]) {
594: if(str[l]=='~' && str[l+1]) {
595: if(!(useron.misc&ANSI))
596: outchar('(');
597: l++;
598: if(!ctrl_a_codes)
599: attr(color[clr_mnehigh]);
600: outchar(str[l]);
601: l++;
602: if(!(useron.misc&ANSI))
603: outchar(')');
604: if(!ctrl_a_codes)
605: attr(color[clr_mnelow]); }
606: else {
607: if(str[l]==1) { /* ctrl-a */
608: ctrl_a(str[++l]); /* skip the ctrl-a */
609: l++; } /* skip the attribute code */
610: else
611: outchar(str[l++]); } }
612: if(!ctrl_a_codes)
613: attr(color[clr_mnecmd]);
614: }
615:
616: /****************************************************************************/
617: /* Prompts user for Y or N (yes or no) and CR is interpreted as a Y */
618: /* Returns 1 for Y or 0 for N */
619: /* Called from quite a few places */
620: /****************************************************************************/
621: char yesno(char *str)
622: {
623: char ch;
624:
625: strcpy(question,str);
626: SYNC;
627: if(useron.misc&WIP) {
628: strip_ctrl(question);
629: menu("YESNO"); }
630: else
631: bprintf(text[YesNoQuestion],str);
632: while(online) {
633: if(sys_status&SS_ABORT)
634: ch=text[YN][1];
635: else
636: ch=getkey(K_UPPER|K_COLD);
637: if(ch==text[YN][0] || ch==CR) {
638: if(bputs(text[Yes]))
639: CRLF;
640: lncntr=0;
641: return(1); }
642: if(ch==text[YN][1]) {
643: if(bputs(text[No]))
644: CRLF;
645: lncntr=0;
646: return(0); } }
647: return(1);
648: }
649:
650: /****************************************************************************/
651: /* Prompts user for N or Y (no or yes) and CR is interpreted as a N */
652: /* Returns 1 for N or 0 for Y */
653: /* Called from quite a few places */
654: /****************************************************************************/
655: char noyes(char *str)
656: {
657: char ch;
658:
659: strcpy(question,str);
660: SYNC;
661: if(useron.misc&WIP) {
662: strip_ctrl(question);
663: menu("NOYES"); }
664: else
665: bprintf(text[NoYesQuestion],str);
666: while(online) {
667: if(sys_status&SS_ABORT)
668: ch=text[YN][1];
669: else
670: ch=getkey(K_UPPER|K_COLD);
671: if(ch==text[YN][1] || ch==CR) {
672: if(bputs(text[No]))
673: CRLF;
674: lncntr=0;
675: return(1); }
676: if(ch==text[YN][0]) {
677: if(bputs(text[Yes]))
678: CRLF;
679: lncntr=0;
680: return(0); } }
681: return(1);
682: }
683:
684: /****************************************************************************/
685: /* Waits for remote or local user to hit a key that is contained inside str.*/
686: /* 'str' should contain uppercase characters only. When a valid key is hit, */
687: /* it is echoed (upper case) and is the return value. */
688: /* Called from quite a few functions */
689: /****************************************************************************/
690: long getkeys(char *str, ulong max)
691: {
692: uchar ch,n=0,c;
693: ulong i=0;
694:
695: strupr(str);
696: while(online) {
697: ch=getkey(K_UPPER);
698: if(max && ch>0x7f) /* extended ascii chars are digits to isdigit() */
699: continue;
700: if(sys_status&SS_ABORT) { /* return -1 if Ctrl-C hit */
701: attr(LIGHTGRAY);
702: CRLF;
703: lncntr=0;
704: return(-1); }
705: if(ch && !n && (strchr(str,ch))) { /* return character if in string */
706: outchar(ch);
707: if(useron.misc&COLDKEYS && ch>SP) {
708: while(online && !(sys_status&SS_ABORT)) {
709: c=getkey(0);
710: if(c==CR || c==BS)
711: break; }
712: if(sys_status&SS_ABORT) {
713: CRLF;
714: return(-1); }
715: if(c==BS) {
716: bputs("\b \b");
717: continue; } }
718: attr(LIGHTGRAY);
719: CRLF;
720: lncntr=0;
721: return(ch); }
722: if(ch==CR && max) { /* return 0 if no number */
723: attr(LIGHTGRAY);
724: CRLF;
725: lncntr=0;
726: if(n)
727: return(i|0x80000000L); /* return number plus high bit */
728: return(0); }
729: if(ch==BS && n) {
730: bputs("\b \b");
731: i/=10;
732: n--; }
733: else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
734: i*=10;
735: n++;
736: i+=ch&0xf;
737: outchar(ch);
738: if(i*10>max && !(useron.misc&COLDKEYS)) {
739: attr(LIGHTGRAY);
740: CRLF;
741: lncntr=0;
742: return(i|0x80000000L); } } }
743: return(-1);
744: }
745:
746: void center(char *str)
747: {
748: int i,j;
749:
750: j=bstrlen(str);
751: for(i=0;i<(80-j)/2;i++)
752: outchar(SP);
753: bputs(str);
754: CRLF;
755: }
756:
757:
758: int uselect(int add, int n, char *title, char *item, char *ar)
759: {
760: static uint total,num[500];
761: char str[128];
762: int i,t;
763:
764: if(add) {
765: if(ar && !chk_ar(ar,useron))
766: return(0);
767: if(!total)
768: bprintf(text[SelectItemHdr],title);
769: num[total++]=n;
770: bprintf(text[SelectItemFmt],total,item);
771: return(0); }
772:
773: if(!total)
774: return(-1);
775:
776: for(i=0;i<total;i++)
777: if(num[i]==n)
778: break;
779: if(i==total)
780: i=0;
781: sprintf(str,text[SelectItemWhich],i+1);
782: mnemonics(str);
783: i=getnum(total);
784: t=total;
785: total=0;
786: if(i<0)
787: return(-1);
788: if(!i) { /* User hit ENTER, use default */
789: for(i=0;i<t;i++)
790: if(num[i]==n)
791: return(num[i]);
792: if(n<t)
793: return(num[n]);
794: return(-1); }
795: return(num[i-1]);
796: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.