diff options
Diffstat (limited to 'process.c')
-rw-r--r-- | process.c | 1113 |
1 files changed, 791 insertions, 322 deletions
@@ -21,9 +21,6 @@ **************************************************************** */ -#include "rcs.h" -RCS_ID("$Id: process.c,v 1.28 1994/09/06 17:00:12 mlschroe Exp $ FAU") - #include <sys/types.h> #include <sys/stat.h> #include <signal.h> @@ -60,17 +57,18 @@ extern int log_flush, logtstamp_on, logtstamp_after; extern char *VisualBellString; extern int VBellWait, MsgWait, MsgMinWait, SilenceWait; extern char SockPath[], *SockName; -extern int TtyMode, auto_detach; -extern int iflag; +extern int TtyMode, auto_detach, use_altscreen; +extern int iflag, maxwin; extern int use_hardstatus, visual_bell; #ifdef COLOR -extern int attr2color[]; +extern int attr2color[][4]; extern int nattr2color; #endif extern int hardstatusemu; extern char *printcmd; extern int default_startup; extern int defobuflimit; +extern int defnonblock; extern int ZombieKey_destroy; extern int ZombieKey_resurrect; #ifdef AUTO_NUKE @@ -96,7 +94,6 @@ extern struct acluser *EffectiveAclUser; /* acl.c */ #endif extern struct term term[]; /* terminal capabilities */ #ifdef MAPKEYS -extern int maptimeout; extern char *kmapdef[]; extern char *kmapadef[]; extern char *kmapmdef[]; @@ -109,19 +106,20 @@ extern char *screenencodings; static int CheckArgNum __P((int, char **)); static void ClearAction __P((struct action *)); +static void SaveAction __P((struct action *, int, char **, int *)); static int NextWindow __P((void)); static int PreviousWindow __P((void)); static int MoreWindows __P((void)); static void LogToggle __P((int)); static void ShowInfo __P((void)); static void ShowDInfo __P((void)); -static char **SaveArgs __P((char **)); static struct win *WindowByName __P((char *)); static int WindowByNumber __P((char *)); static int ParseOnOff __P((struct action *, int *)); -static int ParseWinNum __P((struct action *act, int *)); -static int ParseBase __P((struct action *act, char *, int *, int, char *)); -static char *ParseChar __P((char *, char *)); +static int ParseWinNum __P((struct action *, int *)); +static int ParseBase __P((struct action *, char *, int *, int, char *)); +static int ParseNum1000 __P((struct action *, int *)); +static char **SaveArgs __P((char **)); static int IsNum __P((char *, int)); static void Colonfin __P((char *, int, char *)); static void InputSelect __P((void)); @@ -146,12 +144,10 @@ static void pow_detach_fn __P((char *, int, char *)); #endif static void digraph_fn __P((char *, int, char *)); static void confirm_fn __P((char *, int, char *)); -#ifdef MAPKEYS -static int StuffKey __P((int)); -#endif -static int IsOnDisplay __P((struct win *)); +static int IsOnDisplay __P((struct win *)); static void ResizeRegions __P((char*)); static void ResizeFin __P((char *, int, char *)); +static struct action *FindKtab __P((char *, int)); extern struct layer *flayer; @@ -188,6 +184,18 @@ struct plop plop_tab[MAX_PLOP_DEFS]; int TtyMode = PTYMODE; int hardcopy_append = 0; int all_norefresh = 0; +#ifdef ZMODEM +int zmodem_mode = 0; +char *zmodem_sendcmd; +char *zmodem_recvcmd; +static char *zmodes[4] = {"off", "auto", "catch", "pass"}; +#endif + +int idletimo; +struct action idleaction; +#ifdef BLANKER_PRG +char **blankerprg; +#endif struct action ktab[256]; /* command key translation table */ struct kclass { @@ -198,13 +206,12 @@ struct kclass { struct kclass *kclasses; #ifdef MAPKEYS -struct action umtab[KMAP_KEYS+KMAP_AKEYS+KMAP_EXT]; -struct action dmtab[KMAP_KEYS+KMAP_AKEYS+KMAP_EXT]; -struct action mmtab[KMAP_KEYS+KMAP_AKEYS+KMAP_EXT]; - -char *kmap_extras[KMAP_EXT]; -int kmap_extras_fl[KMAP_EXT]; - +struct action umtab[KMAP_KEYS+KMAP_AKEYS]; +struct action dmtab[KMAP_KEYS+KMAP_AKEYS]; +struct action mmtab[KMAP_KEYS+KMAP_AKEYS]; +struct kmap_ext *kmap_exts; +int kmap_extn; +static int maptimeout = 300; #endif @@ -398,16 +405,20 @@ InitKeytab() { ktab[i].nr = RC_ILLEGAL; ktab[i].args = noargs; + ktab[i].argl = 0; } #ifdef MAPKEYS - for (i = 0; i < KMAP_KEYS+KMAP_AKEYS+KMAP_EXT; i++) + for (i = 0; i < KMAP_KEYS+KMAP_AKEYS; i++) { umtab[i].nr = RC_ILLEGAL; umtab[i].args = noargs; + umtab[i].argl = 0; dmtab[i].nr = RC_ILLEGAL; dmtab[i].args = noargs; + dmtab[i].argl = 0; mmtab[i].nr = RC_ILLEGAL; mmtab[i].args = noargs; + mmtab[i].argl = 0; } argarr[1] = 0; for (i = 0; i < NKMAPDEF; i++) @@ -419,8 +430,7 @@ InitKeytab() if (kmapdef[i] == 0) continue; argarr[0] = kmapdef[i]; - dmtab[i + (KMAPDEFSTART - T_CAPS)].nr = RC_STUFF; - dmtab[i + (KMAPDEFSTART - T_CAPS)].args = SaveArgs(argarr); + SaveAction(dmtab + i + (KMAPDEFSTART - T_CAPS), RC_STUFF, argarr, 0); } for (i = 0; i < NKMAPADEF; i++) { @@ -431,8 +441,7 @@ InitKeytab() if (kmapadef[i] == 0) continue; argarr[0] = kmapadef[i]; - dmtab[i + (KMAPADEFSTART - T_CURSOR + KMAP_KEYS)].nr = RC_STUFF; - dmtab[i + (KMAPADEFSTART - T_CURSOR + KMAP_KEYS)].args = SaveArgs(argarr); + SaveAction(dmtab + i + (KMAPADEFSTART - T_CURSOR + KMAP_KEYS), RC_STUFF, argarr, 0); } for (i = 0; i < NKMAPMDEF; i++) { @@ -444,8 +453,7 @@ InitKeytab() continue; argarr[0] = kmapmdef[i]; argarr[1] = 0; - mmtab[i + (KMAPMDEFSTART - T_CAPS)].nr = RC_STUFF; - mmtab[i + (KMAPMDEFSTART - T_CAPS)].args = SaveArgs(argarr); + SaveAction(mmtab + i + (KMAPMDEFSTART - T_CAPS), RC_STUFF, argarr, 0); } #endif @@ -496,8 +504,7 @@ InitKeytab() char *args[2]; args[0] = "-"; args[1] = NULL; - ktab['-'].nr = RC_SELECT; - ktab['-'].args = SaveArgs(args); + SaveAction(ktab + '-', RC_SELECT, args, 0); } for (i = 0; i < ((MAXWIN < 10) ? MAXWIN : 10); i++) { @@ -505,16 +512,14 @@ InitKeytab() args[0] = arg1; args[1] = 0; sprintf(arg1, "%d", i); - ktab['0' + i].nr = RC_SELECT; - ktab['0' + i].args = SaveArgs(args); + SaveAction(ktab + '0' + i, RC_SELECT, args, 0); } ktab['\''].nr = RC_SELECT; /* calling a window by name */ { char *args[2]; args[0] = "-b"; args[1] = 0; - ktab['"'].nr = RC_WINDOWLIST; - ktab['"'].args = SaveArgs(args); + SaveAction(ktab + '"', RC_WINDOWLIST, args, 0); } ktab[Ctrl('G')].nr = RC_VBELL; ktab[':'].nr = RC_COLON; @@ -524,9 +529,8 @@ InitKeytab() char *args[2]; args[0] = "."; args[1] = 0; - ktab[']'].args = SaveArgs(args); - ktab[Ctrl(']')].args = SaveArgs(args); - ktab[']'].nr = ktab[Ctrl(']')].nr = RC_PASTE; + SaveAction(ktab + ']', RC_PASTE, args, 0); + SaveAction(ktab + Ctrl(']'), RC_PASTE, args, 0); } ktab['{'].nr = RC_HISTORY; ktab['}'].nr = RC_HISTORY; @@ -559,9 +563,13 @@ InitKeytab() ClearAction(&ktab[DefaultMetaEsc]); ktab[DefaultMetaEsc].nr = RC_META; } + + idleaction.nr = RC_BLANKER; + idleaction.args = noargs; + idleaction.argl = 0; } -struct action * +static struct action * FindKtab(class, create) char *class; int create; @@ -590,7 +598,7 @@ int create; return 0; } kp->name = SaveStr(class); - for (i = 0; i < sizeof(kp->ktab)/sizeof(*kp->ktab); i++) + for (i = 0; i < (int)(sizeof(kp->ktab)/sizeof(*kp->ktab)); i++) { kp->ktab[i].nr = RC_ILLEGAL; kp->ktab[i].args = noargs; @@ -616,6 +624,7 @@ struct action *act; free(*p); free((char *)act->args); act->args = noargs; + act->argl = 0; } /* @@ -636,7 +645,7 @@ char *ibuf; int ilen; { int ch, slen; - unsigned char *s; + unsigned char *s, *q; int i, l; char *p; @@ -647,7 +656,7 @@ int ilen; evdeq(&D_mapev); slen = ilen; s = (unsigned char *)ibuf; - while(ilen-- > 0) + while (ilen-- > 0) { ch = *s++; if (D_dontmap || !D_nseqs) @@ -657,47 +666,84 @@ int ilen; } for (;;) { - if (*(unsigned char *)D_seqp != ch) + debug3("cmp %c %c[%d]\n", ch, *D_seqp, D_seqp - D_kmaps); + if (*D_seqp != ch) { - l = *((unsigned char *)D_seqp + (KMAP_OFF - KMAP_SEQ)); + l = D_seqp[D_seqp[-D_seql-1] + 1]; if (l) { - D_seqp += sizeof(struct kmap) * l; + D_seqp += l * 2 + 4; + debug1("miss %d\n", D_seqp - D_kmaps); continue; } + debug("complete miss\n"); D_mapdefault = 0; l = D_seql; - p = D_seqp - l; + p = (char *)D_seqp - l; D_seql = 0; - D_seqp = D_kmaps[0].seq; - if (l) + D_seqp = D_kmaps + 3; + if (l == 0) + break; + if ((q = D_seqh) != 0) { - ProcessInput2(p, l); + D_seqh = 0; + i = q[0] << 8 | q[1]; + i &= ~KMAP_NOTIMEOUT; + debug1("Mapping former hit #%d - ", i); + debug2("%d(%s) - ", q[2], q + 3); + if (StuffKey(i)) + ProcessInput2((char *)q + 3, q[2]); if (display == 0) return; + l -= q[2]; + p += q[2]; } - break; + else + D_dontmap = 1; + debug1("flush old %d\n", l); + ProcessInput(p, l); + if (display == 0) + return; + evdeq(&D_mapev); + continue; } if (D_seql++ == 0) { /* Finish old stuff */ slen -= ilen + 1; - ProcessInput2(ibuf, slen); + debug1("finish old %d\n", slen); + if (slen) + ProcessInput2(ibuf, slen); if (display == 0) return; + D_seqh = 0; } ibuf = (char *)s; slen = ilen; - ch = -1; - if (*++D_seqp == 0) - { - i = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ) - D_kmaps; + D_seqp++; + l = D_seql; + debug2("length am %d, want %d\n", l, D_seqp[-l - 1]); + if (l == D_seqp[-l - 1]) + { + if (D_seqp[l] != l) + { + q = D_seqp + 1 + l; + if (D_kmaps + D_nseqs > q && q[2] > l && !bcmp(D_seqp - l, q + 3, l)) + { + debug1("have another mapping (%s), delay execution\n", q + 3); + D_seqh = D_seqp - 3 - l; + D_seqp = q + 3 + l; + break; + } + } + i = D_seqp[-l - 3] << 8 | D_seqp[-l - 2]; + i &= ~KMAP_NOTIMEOUT; debug1("Mapping #%d - ", i); - i = D_kmaps[i].nr & ~KMAP_NOTIMEOUT; - l = D_seql; - p = D_seqp - l; + p = (char *)D_seqp - l; + debug2("%d(%s) - ", l, p); D_seql = 0; - D_seqp = D_kmaps[0].seq; + D_seqp = D_kmaps + 3; + D_seqh = 0; if (StuffKey(i)) ProcessInput2(p, l); if (display == 0) @@ -708,19 +754,18 @@ int ilen; } if (D_seql) { - struct kmap *km; debug("am in sequence -> check for timeout\n"); - km = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ); - i = *(D_seqp - 1 + (KMAP_OFF - KMAP_SEQ)); - if (i == 0) - i = D_nseqs - (km - D_kmaps); - for (; i; km++, i--) - if (km->nr & KMAP_NOTIMEOUT) - break; - if (i == 0) + l = D_seql; + for (s = D_seqp; ; s += i * 2 + 4) { - SetTimeout(&D_mapev, maptimeout/1000); - evenq(&D_mapev); + if (s[-l-3] & KMAP_NOTIMEOUT >> 8) + break; + if ((i = s[s[-l-1] + 1]) == 0) + { + SetTimeout(&D_mapev, maptimeout); + evenq(&D_mapev); + break; + } } } ProcessInput2(ibuf, slen); @@ -801,15 +846,6 @@ struct paster *pa; struct display *d = display; #ifdef COPY_PASTE - if (!pa && p && p->w_paster.pa_pastelen) - { - debug("layer is busy - beep!\n"); - WBell(p, visual_bell); - *bufp += *lenp; - *lenp = 0; - display = d; - return; - } /* XXX -> PasteStart */ if (pa && *lenp > 1 && p && p->w_slowpaste) { @@ -821,6 +857,17 @@ struct paster *pa; #endif while (flayer && *lenp) { +#ifdef COPY_PASTE + if (!pa && p && p->w_paster.pa_pastelen && flayer == p->w_paster.pa_pastelayer) + { + debug("layer is busy - beep!\n"); + WBell(p, visual_bell); + *bufp += *lenp; + *lenp = 0; + display = d; + return; + } +#endif oldlen = *lenp; LayProcess(bufp, lenp); #ifdef COPY_PASTE @@ -979,6 +1026,7 @@ int key; { int nr = act->nr; char **args = act->args; + int *argl = act->argl; struct win *p; int argc, i, n, msgok; char *s; @@ -1033,6 +1081,16 @@ int key; SetForeWindow((struct win *)0); Activate(0); } + else if (args[0][0] == '.' && !args[0][1]) + { + if (!fore) + Msg(0, "select . needs a window"); + else + { + SetForeWindow(fore); + Activate(0); + } + } else if (ParseWinNum(act, &n) == 0) SwitchWindow(n); break; @@ -1195,25 +1253,62 @@ int key; Msg(0, "Sorry, screen was compiled without -DDEBUG option."); #endif break; +#ifdef ZMODEM + case RC_ZMODEM: + if (*args && !strcmp(*args, "sendcmd")) + { + if (args[1]) + { + free(zmodem_sendcmd); + zmodem_sendcmd = SaveStr(args[1]); + } + if (msgok) + Msg(0, "zmodem sendcmd: %s", zmodem_sendcmd); + break; + } + if (*args && !strcmp(*args, "recvcmd")) + { + if (args[1]) + { + free(zmodem_recvcmd); + zmodem_recvcmd = SaveStr(args[1]); + } + if (msgok) + Msg(0, "zmodem recvcmd: %s", zmodem_recvcmd); + break; + } + if (*args) + { + for (i = 0; i < 4; i++) + if (!strcmp(zmodes[i], *args)) + break; + if (i == 4 && !strcmp(*args, "on")) + i = 1; + if (i == 4) + { + Msg(0, "usage: zmodem off|auto|catch|pass"); + break; + } + zmodem_mode = i; + } + if (msgok) + Msg(0, "zmodem mode is %s", zmodes[zmodem_mode]); + break; +#endif case RC_ZOMBIE: { - char ch2 = 0; - if (!(s = *args)) { ZombieKey_destroy = 0; break; } - if (!(s = ParseChar(s, &ch)) || *s) - { - if (!s || !(s = ParseChar(s, &ch2)) || *s) - { - Msg(0, "%s:zombie: one or two characters expected.", rc_name); - break; - } - } - ZombieKey_destroy = ch; - ZombieKey_resurrect = ch2; + if (*argl == 0 || *argl > 2) + { + Msg(0, "%s:zombie: one or two characters expected.", rc_name); + break; + } + ZombieKey_destroy = args[0][0]; + ZombieKey_resurrect = *argl == 2 ? args[0][1] : 0; } break; case RC_WALL: @@ -1272,7 +1367,7 @@ int key; if (D_user != u) continue; debug1("AT display %s\n", D_usertty); - DoCommand(args + 1); + DoCommand(args + 1, argl + 1); if (display) Msg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); @@ -1301,7 +1396,7 @@ int key; strncmp(args[0], D_usertty + 8, n))) continue; debug1("AT display %s\n", D_usertty); - DoCommand(args + 1); + DoCommand(args + 1, argl + 1); if (display) Msg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); @@ -1344,7 +1439,7 @@ int key; if (fore->w_layer.l_cvlist) display = fore->w_layer.l_cvlist->c_display; flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer; - DoCommand(args + 1); /* may destroy our display */ + DoCommand(args + 1, argl + 1); /* may destroy our display */ if (fore && fore->w_layer.l_cvlist) { display = fore->w_layer.l_cvlist->c_display; @@ -1364,7 +1459,8 @@ int key; debug2("AT window %d (%s)\n", fore->w_number, fore->w_title); if (fore->w_layer.l_cvlist) display = fore->w_layer.l_cvlist->c_display; - DoCommand(args + 1); + flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer; + DoCommand(args + 1, argl + 1); if (fore && fore->w_layer.l_cvlist) { display = fore->w_layer.l_cvlist->c_display; @@ -1411,11 +1507,12 @@ int key; Input("Copy to register:", 1, INP_RAW, copy_reg_fn, NULL); break; } - if (((s = ParseChar(s, &ch)) == NULL) || *s) + if (*argl != 1) { Msg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.", rc_name); break; } + ch = args[0][0]; /* * With two arguments we *really* read register contents from file */ @@ -1468,17 +1565,21 @@ int key; Msg(0, "%s: register: illegal number of arguments.", rc_name); break; } - if ((s = ParseChar(*args, &ch)) == 0 || *s) - Msg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name); + if (*argl != 1) + { + Msg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name); + break; + } + ch = args[0][0]; #ifdef COPY_PASTE - else if (ch == '.') + if (ch == '.') { if (user->u_plop.buf != NULL) UserFreeCopyBuffer(user); if (args[1] && args[1][0]) { - user->u_plop.buf = SaveStr(args[1]); - user->u_plop.len = strlen(user->u_plop.buf); + user->u_plop.buf = SaveStrn(args[1], argl[1]); + user->u_plop.len = argl[1]; #ifdef ENCODINGS user->u_plop.enc = i; #endif @@ -1491,8 +1592,8 @@ int key; if (plp->buf) free(plp->buf); - plp->buf = SaveStr(args[1]); - plp->len = strlen(plp->buf); + plp->buf = SaveStrn(args[1], argl[1]); + plp->len = argl[1]; #ifdef ENCODINGS plp->enc = i; #endif @@ -1504,15 +1605,17 @@ int key; Input("Process register:", 1, INP_RAW, process_fn, NULL); break; } - if ((s = ParseChar(s, &ch)) == NULL || *s) + if (*argl != 1) { Msg(0, "%s: process: character, ^x, or (octal) \\032 expected.", rc_name); break; } + ch = args[0][0]; process_fn(&ch, 0, NULL); break; case RC_STUFF: s = *args; + n = *argl; if (args[1]) { if (strcmp(s, "-k")) @@ -1536,8 +1639,8 @@ int key; s = display ? D_tcs[i].str : 0; if (s == 0) break; + n = strlen(s); } - n = strlen(s); while(n) LayProcess(&s, &n); break; @@ -1616,7 +1719,7 @@ int key; if (*args) { if (ParseNum(act, &n)) - for (n = 0; n < sizeof(types)/sizeof(*types); n++) + for (n = 0; n < (int)(sizeof(types)/sizeof(*types)); n++) { for (i = 0; i < 4; i++) { @@ -1629,7 +1732,7 @@ int key; if (i == 4) break; } - if (n < 0 || n >= sizeof(types)/sizeof(*types)) + if (n < 0 || n >= (int)(sizeof(types)/sizeof(*types))) Msg(0, "%s invalid, chose one of %s, %s or %s", *args, types[0], types[1], types[2]); else { @@ -1785,7 +1888,7 @@ int key; if (*args == 0) InputAKA(); else - ChangeAKA(fore, *args, 20); + ChangeAKA(fore, *args, strlen(*args)); break; case RC_COLON: Input(":", 100, INP_COOKED, Colonfin, NULL); @@ -1876,6 +1979,10 @@ int key; break; case RC_RESET: ResetAnsiState(fore); +#ifdef ZMODEM + if (fore->w_zdisplay) + zmodem_abort(fore, fore->w_zdisplay); +#endif WriteString(fore, "\033c", 2); break; case RC_MONITOR: @@ -1920,9 +2027,15 @@ int key; #endif case RC_WINDOWLIST: if (!*args) - display_wlist(0); + display_wlist(0, WLIST_NUM); + else if (!strcmp(*args, "-m") && !args[1]) + display_wlist(0, WLIST_MRU); else if (!strcmp(*args, "-b") && !args[1]) - display_wlist(1); + display_wlist(1, WLIST_NUM); + else if (!strcmp(*args, "-b") && !strcmp(args[1], "-m") && !args[2]) + display_wlist(1, WLIST_MRU); + else if (!strcmp(*args, "-m") && !strcmp(args[1], "-b") && !args[2]) + display_wlist(1, WLIST_MRU); else if (!strcmp(*args, "string")) { if (args[1]) @@ -1977,6 +2090,7 @@ int key; case RC_HISTORY: { static char *pasteargs[] = {".", 0}; + static int pasteargl[] = {1}; if (flayer->l_layfn != &WinLf) { @@ -1988,6 +2102,7 @@ int key; if (user->u_plop.buf == NULL) break; args = pasteargs; + argl = pasteargl; } /*FALLTHROUGH*/ case RC_PASTE: @@ -2012,7 +2127,7 @@ int key; * with two arguments we paste into a destination register * (no window needed here). */ - if (args[1] && ((s = ParseChar(args[1], &dch)) == NULL || *s)) + if (args[1] && argl[1] != 1) { Msg(0, "%s: paste destination: character, ^x, or (octal) \\032 expected.", rc_name); @@ -2108,6 +2223,7 @@ int key; * we have two arguments, the second is already in dch. * use this as destination rather than the window. */ + dch = args[1][0]; if (dch == '.') { if (user->u_plop.buf != NULL) @@ -2221,7 +2337,11 @@ int key; break; #endif /* COPY_PASTE */ case RC_ESCAPE: - if (ParseEscape(user, *args)) + if (*argl == 0) + SetEscape(user, -1, -1); + else if (*argl == 2) + SetEscape(user, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]); + else { Msg(0, "%s: two characters required after escape.", rc_name); break; @@ -2233,7 +2353,11 @@ int key; break; /* FALLTHROUGH */ case RC_DEFESCAPE: - if (ParseEscape(NULL, *args)) + if (*argl == 0) + SetEscape(NULL, -1, -1); + else if (*argl == 2) + SetEscape(NULL, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]); + else { Msg(0, "%s: two characters required after defescape.", rc_name); break; @@ -2331,16 +2455,30 @@ int key; debug("new termcap made\n"); break; case RC_ECHO: - if (!msgok) + if (!msgok && (!rc_name || strcmp(rc_name, "-X"))) break; /* * user typed ^A:echo... well, echo isn't FinishRc's job, * but as he wanted to test us, we show good will */ - if (*args && (args[1] == 0 || (strcmp(args[1], "-n") == 0 && args[2] == 0))) - Msg(0, "%s", args[1] ? args[1] : *args); + if (argc > 1 && !strcmp(*args, "-n")) + { + args++; + argc--; + } + s = *args; + if (argc > 1 && !strcmp(*args, "-p")) + { + args++; + argc--; + s = *args; + if (s) + s = MakeWinMsg(s, fore, '%'); + } + if (s) + Msg(0, "%s", s); else - Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name); + Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name); break; case RC_BELL: case RC_BELL_MSG: @@ -2594,26 +2732,26 @@ int key; Msg(0, "switched to visual bell."); break; case RC_VBELLWAIT: - if (ParseNum(act, &VBellWait) == 0 && msgok) - Msg(0, "vbellwait set to %d seconds", VBellWait); + if (ParseNum1000(act, &VBellWait) == 0 && msgok) + Msg(0, "vbellwait set to %.10g seconds", VBellWait/1000.); break; case RC_MSGWAIT: - if (ParseNum(act, &MsgWait) == 0 && msgok) - Msg(0, "msgwait set to %d seconds", MsgWait); + if (ParseNum1000(act, &MsgWait) == 0 && msgok) + Msg(0, "msgwait set to %.10g seconds", MsgWait/1000.); break; case RC_MSGMINWAIT: - if (ParseNum(act, &MsgMinWait) == 0 && msgok) - Msg(0, "msgminwait set to %d seconds", MsgMinWait); + if (ParseNum1000(act, &MsgMinWait) == 0 && msgok) + Msg(0, "msgminwait set to %.10g seconds", MsgMinWait/1000.); break; case RC_SILENCEWAIT: - if ((ParseNum(act, &SilenceWait) == 0) && msgok) - { - if (SilenceWait < 1) - SilenceWait = 1; - for (p = windows; p; p = p->w_next) - p->w_silencewait = SilenceWait; - Msg(0, "silencewait set to %d seconds", SilenceWait); - } + if (ParseNum(act, &SilenceWait)) + break; + if (SilenceWait < 1) + SilenceWait = 1; + for (p = windows; p; p = p->w_next) + p->w_silencewait = SilenceWait; + if (msgok) + Msg(0, "silencewait set to %d seconds", SilenceWait); break; case RC_NUMBER: if (*args == 0) @@ -2622,7 +2760,7 @@ int key; { int old = fore->w_number; - if (ParseNum(act, &n) || n >= MAXWIN) + if (ParseNum(act, &n) || n >= maxwin) break; p = wtab[n]; wtab[n] = fore; @@ -2729,7 +2867,7 @@ int key; s = 0; if (ParseSaveStr(act, &s)) break; - if (!*s || strlen(s) + (SockName - SockPath) > MAXPATHLEN - 13) + if (!*s || strlen(s) + (SockName - SockPath) > MAXPATHLEN - 13 || index(s, '/')) { Msg(0, "%s: bad session name '%s'\n", rc_name, s); free(s); @@ -2786,17 +2924,12 @@ int key; fore->w_number, fore->w_slowpaste); break; case RC_MARKKEYS: - s = 0; - if (ParseSaveStr(act, &s)) - break; - if (CompileKeys(s, mark_key_tab)) + if (CompileKeys(*args, *argl, mark_key_tab)) { Msg(0, "%s: markkeys: syntax error.", rc_name); - free(s); break; } debug1("markkeys %s\n", *args); - free(s); break; # ifdef FONT case RC_PASTEFONT: @@ -2885,14 +3018,14 @@ int key; if (ktabp == 0) break; args += 2; + argl += 2; } - if ((s = ParseChar(*args, &ch)) == 0 || *s) + if (*argl != 1) { - Msg(0, "%s: bind: character, ^x, or (octal) \\032 expected.", - rc_name); + Msg(0, "%s: bind: character, ^x, or (octal) \\032 expected.", rc_name); break; } - n = (unsigned char)ch; + n = (unsigned char)args[0][0]; if (args[1]) { if ((i = FindCommnr(args[1])) == RC_ILLEGAL) @@ -2903,9 +3036,7 @@ int key; if (CheckArgNum(i, args + 2) < 0) break; ClearAction(&ktabp[n]); - ktabp[n].nr = i; - if (args[2]) - ktabp[n].args = SaveArgs(args + 2); + SaveAction(ktabp + n, i, args + 2, argl + 2); } else ClearAction(&ktabp[n]); @@ -2918,8 +3049,9 @@ int key; int newnr, fl = 0, kf = 0, af = 0, df = 0, mf = 0; struct display *odisp = display; int used = 0; + struct kmap_ext *kme; - for (; *args && **args == '-'; args++) + for (; *args && **args == '-'; args++, argl++) { if (strcmp(*args, "-t") == 0) fl = KMAP_NOTIMEOUT; @@ -2934,6 +3066,7 @@ int key; else if (strcmp(*args, "--") == 0) { args++; + argl++; break; } else @@ -2964,27 +3097,48 @@ int key; Msg(0, "%s: bindkey: -a only works with -k", rc_name); break; } - for (i = 0; i < KMAP_EXT; i++) - if (kmap_extras[i] == 0) + if (*argl == 0) + { + Msg(0, "%s: bindkey: empty string makes no sense", rc_name); + break; + } + for (i = 0, kme = kmap_exts; i < kmap_extn; i++, kme++) + if (kme->str == 0) { if (args[1]) break; } else - if (strcmp(kmap_extras[i], *args) == 0) + if (*argl == (kme->fl & ~KMAP_NOTIMEOUT) && bcmp(kme->str, *args, *argl) == 0) break; - if (i == KMAP_EXT) + if (i == kmap_extn) { - Msg(0, args[1] ? "%s: bindkey: no more room for keybinding" : "%s: bindkey: keybinding not found", rc_name); - break; + if (!args[1]) + { + Msg(0, "%s: bindkey: keybinding not found", rc_name); + break; + } + kmap_extn += 8; + kmap_exts = (struct kmap_ext *)xrealloc((char *)kmap_exts, kmap_extn * sizeof(*kmap_exts)); + kme = kmap_exts + i; + bzero((char *)kme, 8 * sizeof(*kmap_exts)); + for (; i < kmap_extn; i++, kme++) + { + kme->str = 0; + kme->dm.nr = kme->mm.nr = kme->um.nr = RC_ILLEGAL; + kme->dm.args = kme->mm.args = kme->um.args = noargs; + } + i -= 8; + kme -= 8; } - if (df == 0 && dmtab[i + KMAP_KEYS + KMAP_AKEYS].nr != RC_ILLEGAL) + if (df == 0 && kme->dm.nr != RC_ILLEGAL) used = 1; - if (mf == 0 && mmtab[i + KMAP_KEYS + KMAP_AKEYS].nr != RC_ILLEGAL) + if (mf == 0 && kme->mm.nr != RC_ILLEGAL) used = 1; - if ((df || mf) && umtab[i + KMAP_KEYS + KMAP_AKEYS].nr != RC_ILLEGAL) + if ((df || mf) && kme->um.nr != RC_ILLEGAL) used = 1; i += KMAP_KEYS + KMAP_AKEYS; + newact = df ? &kme->dm : mf ? &kme->mm : &kme->um; } else { @@ -3000,8 +3154,8 @@ int key; i -= T_CURSOR - KMAP_KEYS; else i -= T_CAPS; + newact = df ? &dmtab[i] : mf ? &mmtab[i] : &umtab[i]; } - newact = df ? &dmtab[i] : mf ? &mmtab[i] : &umtab[i]; if (args[1]) { if ((newnr = FindCommnr(args[1])) == RC_ILLEGAL) @@ -3012,15 +3166,13 @@ int key; if (CheckArgNum(newnr, args + 2) < 0) break; ClearAction(newact); - newact->nr = newnr; - if (args[2]) - newact->args = SaveArgs(args + 2); + SaveAction(newact, newnr, args + 2, argl + 2); if (kf == 0 && args[1]) { - if (kmap_extras[i - (KMAP_KEYS+KMAP_AKEYS)]) - free(kmap_extras[i - (KMAP_KEYS+KMAP_AKEYS)]); - kmap_extras[i - (KMAP_KEYS+KMAP_AKEYS)] = SaveStr(*args); - kmap_extras_fl[i - (KMAP_KEYS+KMAP_AKEYS)] = fl; + if (kme->str) + free(kme->str); + kme->str = SaveStrn(*args, *argl); + kme->fl = fl | *argl; } } else @@ -3029,12 +3181,11 @@ int key; remap(i, args[1] ? 1 : 0); if (kf == 0 && !args[1]) { - i -= KMAP_KEYS + KMAP_AKEYS; - if (!used && kmap_extras[i]) + if (!used && kme->str) { - free(kmap_extras[i]); - kmap_extras[i] = 0; - kmap_extras_fl[i] = 0; + free(kme->str); + kme->str = 0; + kme->fl = 0; } } display = odisp; @@ -3045,15 +3196,15 @@ int key; { if (ParseNum(act, &n)) break; - if (n < 0 || n >= 1000) + if (n < 0) { Msg(0, "%s: maptimeout: illegal time %d", rc_name, n); break; } - maptimeout = n * 1000; + maptimeout = n; } if (*args == 0 || msgok) - Msg(0, "maptimeout is %dms", maptimeout/1000); + Msg(0, "maptimeout is %dms", maptimeout); break; case RC_MAPNOTNEXT: D_dontmap = 1; @@ -3159,14 +3310,55 @@ int key; #endif #ifdef MULTI case RC_NONBLOCK: - if (!ParseSwitch(act, &i) && msgok) - Msg(0, "display set to %sblocking mode.", D_nonblock ? "non" : ""); + i = D_nonblock >= 0; + if (*args && ((args[0][0] >= '0' && args[0][0] <= '9') || args[0][0] == '.')) + { + if (ParseNum1000(act, &i)) + break; + } + else if (!ParseSwitch(act, &i)) + i = i == 0 ? -1 : 1000; + else + break; + if (msgok && i == -1) + Msg(0, "display set to blocking mode"); + else if (msgok && i == 0) + Msg(0, "display set to nonblocking mode, no timeout"); + else if (msgok) + Msg(0, "display set to nonblocking mode, %.10gs timeout", i/1000.); D_nonblock = i; + if (D_nonblock <= 0) + evdeq(&D_blockedev); + break; + case RC_DEFNONBLOCK: + if (*args && ((args[0][0] >= '0' && args[0][0] <= '9') || args[0][0] == '.')) + { + if (ParseNum1000(act, &defnonblock)) + break; + } + else if (!ParseOnOff(act, &defnonblock)) + defnonblock = defnonblock == 0 ? -1 : 1000; + else + break; + if (display && *rc_name) + { + D_nonblock = defnonblock; + if (D_nonblock <= 0) + evdeq(&D_blockedev); + } break; #endif case RC_GR: +#ifdef ENCODINGS + if (fore->w_gr == 2) + fore->w_gr = 0; +#endif if (ParseSwitch(act, &fore->w_gr) == 0 && msgok) Msg(0, "Will %suse GR", fore->w_gr ? "" : "not "); +#ifdef ENCODINGS + if (fore->w_gr == 0 && fore->w_FontE) + fore->w_gr = 2; +#endif break; case RC_C1: if (ParseSwitch(act, &fore->w_c1) == 0 && msgok) @@ -3377,13 +3569,28 @@ int key; #endif #ifdef COLOR case RC_ATTRCOLOR: - if (args[0][0] >= '0' && args[0][0] <= '9') - i = args[0][0] - '0'; + s = args[0]; + if (*s >= '0' && *s <= '9') + i = *s - '0'; else for (i = 0; i < 8; i++) - if (args[0][0] == "dubrsBiI"[i]) + if (*s == "dubrsBiI"[i]) break; - if (args[0][1] || i < 0 || i >= 8) + s++; + nr = 0; + if (*s && s[1] && !s[2]) + { + if (*s == 'd' && s[1] == 'd') + nr = 3; + else if (*s == '.' && s[1] == 'd') + nr = 2; + else if (*s == 'd' && s[1] == '.') + nr = 1; + else if (*s != '.' || s[1] != '.') + s--; + s += 2; + } + if (*s || i < 0 || i >= 8) { Msg(0, "%s: attrcolor: unknown attribute '%s'.", rc_name, args[0]); break; @@ -3393,10 +3600,10 @@ int key; n = ParseAttrColor(args[1], args[2], 1); if (n == -1) break; - attr2color[i] = n; + attr2color[i][nr] = n; n = 0; for (i = 0; i < 8; i++) - if (attr2color[i]) + if (attr2color[i][0] || attr2color[i][1] || attr2color[i][2] || attr2color[i][3]) n |= 1 << i; nattr2color = n; break; @@ -3409,6 +3616,7 @@ int key; if (i == -1) break; ApplyAttrColor(i, &mchar_so); + debug2("--> %x %x\n", mchar_so.attr, mchar_so.color); } if (msgok) #ifdef COLOR @@ -3514,9 +3722,105 @@ int key; for (; *args; args++) { char *ss = SaveStr(*args); - RcLine(ss); + if (*ss) + Colonfin(ss, strlen(ss), (char *)0); free(ss); } + break; + case RC_ALTSCREEN: + (void)ParseSwitch(act, &use_altscreen); + if (msgok) + Msg(0, "Will %sdo alternate screen switching", use_altscreen ? "" : "not "); + break; + case RC_MAXWIN: + if (ParseNum(act, &n)) + break; + if (n < 1) + Msg(0, "illegal maxwin number specified"); + else if (n > maxwin) + Msg(0, "may only decrease maxwin number"); + else + maxwin = n; + break; + case RC_BACKTICK: + if (ParseBase(act, *args, &n, 10, "decimal")) + break; + if (!args[1]) + setbacktick(n, 0, 0, (char **)0); + else + { + int lifespan, tick; + if (argc < 4) + { + Msg(0, "%s: usage: backtick num [lifespan tick cmd args...]", rc_name); + break; + } + if (ParseBase(act, args[1], &lifespan, 10, "decimal")) + break; + if (ParseBase(act, args[2], &tick, 10, "decimal")) + break; + setbacktick(n, lifespan, tick, SaveArgs(args + 3)); + } + WindowChanged(0, '`'); + break; + case RC_BLANKER: +#ifdef BLANKER_PRG + if (blankerprg) + { + RunBlanker(blankerprg); + break; + } +#endif + ClearAll(); + CursorVisibility(-1); + D_blocked = 4; + break; +#ifdef BLANKER_PRG + case RC_BLANKERPRG: + if (blankerprg) + { + char **pp; + for (pp = blankerprg; *pp; pp++) + free(*pp); + free(blankerprg); + blankerprg = 0; + } + if (args[0][0]) + blankerprg = SaveArgs(args); + break; +#endif + case RC_IDLE: + if (*args) + { + struct display *olddisplay = display; + if (!strcmp(*args, "off")) + idletimo = 0; + else if (args[0][0]) + idletimo = atoi(*args) * 1000; + if (argc > 1) + { + if ((i = FindCommnr(args[1])) == RC_ILLEGAL) + { + Msg(0, "%s: idle: unknown command '%s'", rc_name, args[1]); + break; + } + if (CheckArgNum(i, args + 2) < 0) + break; + ClearAction(&idleaction); + SaveAction(&idleaction, i, args + 2, argl + 2); + } + for (display = displays; display; display = display->d_next) + ResetIdle(); + display = olddisplay; + } + if (msgok) + { + if (idletimo) + Msg(0, "idle timeout %ds, %s", idletimo / 1000, comms[idleaction.nr].name); + else + Msg(0, "idle off"); + } + break; default: #ifdef HAVE_BRAILLE /* key == -2: input from braille keybord, msgok always 0 */ @@ -3533,8 +3837,9 @@ int key; } void -DoCommand(argv) +DoCommand(argv, argl) char **argv; +int *argl; { struct action act; @@ -3544,9 +3849,46 @@ char **argv; return; } act.args = argv + 1; + act.argl = argl + 1; DoAction(&act, -1); } +static void +SaveAction(act, nr, args, argl) +struct action *act; +int nr; +char **args; +int *argl; +{ + register int argc = 0; + char **pp; + int *lp; + + if (args) + while (args[argc]) + argc++; + if (argc == 0) + { + act->nr = nr; + act->args = noargs; + act->argl = 0; + return; + } + if ((pp = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) + Panic(0, strnomem); + if ((lp = (int *)malloc((unsigned)(argc) * sizeof(int *))) == 0) + Panic(0, strnomem); + act->nr = nr; + act->args = pp; + act->argl = lp; + while (argc--) + { + *lp = argl ? *argl++ : (int)strlen(*args); + *pp++ = SaveStrn(*args++, *lp++); + } + *pp = 0; +} + static char ** SaveArgs(args) char **args; @@ -3556,7 +3898,7 @@ char **args; while (args[argc]) argc++; - if ((pp = ap = (char **) malloc((unsigned) (argc + 1) * sizeof(char **))) == 0) + if ((pp = ap = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) Panic(0, strnomem); while (argc--) *pp++ = SaveStr(*args++); @@ -3564,6 +3906,7 @@ char **args; return ap; } + /* * buf is split into argument vector args. * leading whitespace is removed. @@ -3574,111 +3917,177 @@ char **args; * argc is returned. */ int -Parse(buf, args) +Parse(buf, bufl, args, argl) char *buf, **args; +int bufl, *argl; { register char *p = buf, **ap = args, *pp; register int delim, argc; + int *lp = argl; + debug2("Parse %d %s\n", bufl, buf); argc = 0; + pp = buf; + delim = 0; for (;;) { while (*p && (*p == ' ' || *p == '\t')) ++p; - if (argc == 0) - { - /* - * Expand hardcoded shortcuts. - * This should not be done here, cause multiple commands per - * line or prefixed commands won't be recognized. - * But as spaces between shortcut character and arguments - * can be ommited this expansion affects tokenisation and - * should be done here. Hmmm. jw. - */ - switch (*p) - { - case '@': - *ap++ = "at"; - /* - * If comments were removed before this shortcut expanded, - * we wouldn't need this hack. - */ - if (p[1] == '#') - *p = '\\'; - while (*(++p) == ' ' || *p == '\t') - ; - argc++; - break; #ifdef PSEUDOS - case '!': - case '|': - *ap++ = "exec"; - if (*p == '!') - p++; - while (*p == ' ' || *p == '\t') - p++; - argc++; - break; -#endif - } + if (argc == 0 && *p == '!') + { + *ap++ = "exec"; + *lp++ = 4; + p++; + argc++; + continue; } - if (*p == '\0' || *p == '#') +#endif + if (*p == '\0' || *p == '#' || *p == '\n') { *p = '\0'; + for (delim = 0; delim < argc; delim++) + debug1("-- %s\n", args[delim]); args[argc] = 0; return argc; } - if (*p == '\\' && p[1] == '#') - p++; if (++argc >= MAXARGS) { Msg(0, "%s: too many tokens.", rc_name); return 0; } - delim = 0; - *ap++ = pp = p; - while (*p && (delim || (*p != ' ' && *p != '\t'))) - { + *ap++ = pp; + + debug1("- new arg %s\n", p); + while (*p) + { if (*p == delim) delim = 0; - else if (!delim && (*p == '"' || *p == '\'')) + else if (delim != '\'' && *p == '\\' && (p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7'))) + { + p++; + if (*p >= '0' && *p <= '7') + { + *pp = *p - '0'; + if (p[1] >= '0' && p[1] <= '7') + { + p++; + *pp = (*pp << 3) | (*p - '0'); + if (p[1] >= '0' && p[1] <= '7') + { + p++; + *pp = (*pp << 3) | (*p - '0'); + } + } + pp++; + } + else + *pp++ = *p; + } + else if (delim != '\'' && *p == '$' && (p[1] == '{' || p[1] == ':' || (p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z') || (p[1] >= '0' && p[1] <= '9') || p[1] == '_')) + + { + char *ps, *pe, op, *v, xbuf[11]; + int vl; + + ps = ++p; + debug1("- var %s\n", ps); + p++; + while (*p) + { + if (*ps == '{' && *p == '}') + break; + if (*ps == ':' && *p == ':') + break; + if (*ps != '{' && *ps != ':' && (*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9') && *p != '_') + break; + p++; + } + pe = p; + if (*ps == '{' || *ps == ':') + { + if (!*p) + { + Msg(0, "%s: bad variable name.", rc_name); + return 0; + } + p++; + } + op = *pe; + *pe = 0; + debug1("- var is '%s'\n", ps); + if (*ps == ':') + v = gettermcapstring(ps + 1); + else + { + if (*ps == '{') + ps++; + v = xbuf; + if (!strcmp(ps, "TERM")) + v = display ? D_termname : "unknown"; + else if (!strcmp(ps, "COLUMNS")) + sprintf(xbuf, "%d", display ? D_width : -1); + else if (!strcmp(ps, "LINES")) + sprintf(xbuf, "%d", display ? D_height : -1); + else + v = getenv(ps); + } + *pe = op; + vl = v ? strlen(v) : 0; + if (vl) + { + debug1("- sub is '%s'\n", v); + if (p - pp < vl) + { + int right = buf + bufl - (p + strlen(p) + 1); + if (right > 0) + { + bcopy(p, p + right, strlen(p) + 1); + p += right; + } + } + if (p - pp < vl) + { + Msg(0, "%s: no space left for variable expansion.", rc_name); + return 0; + } + bcopy(v, pp, vl); + pp += vl; + } + continue; + } + else if (delim != '\'' && *p == '^' && p[1]) + { + p++; + *pp++ = *p == '?' ? '\177' : *p & 0x1f; + } + else if (delim == 0 && (*p == '\'' || *p == '"')) delim = *p; + else if (delim == 0 && (*p == ' ' || *p == '\t' || *p == '\n')) + break; else *pp++ = *p; p++; - } - if (*p == 0) + } + if (delim) { - if (delim) - { - Msg(0, "%s: Missing quote.", rc_name); - return 0; - } + Msg(0, "%s: Missing %c quote.", rc_name, delim); + return 0; } - else + if (*p) p++; *pp = 0; + debug2("- arg done, '%s' rest %s\n", ap[-1], p); + *lp++ = pp - ap[-1]; + pp++; } } -int -ParseEscape(u, p) +void +SetEscape(u, e, me) struct acluser *u; -char *p; +int e, me; { - unsigned char buf[2]; - int e, me; - - if (*p == 0) - e = me = -1; - else - { - if ((p = ParseChar(p, (char *)buf)) == NULL || - (p = ParseChar(p, (char *)buf+1)) == NULL || *p) - return -1; - e = buf[0]; - me = buf[1]; - } if (u) { u->u_Esc = e; @@ -3709,7 +4118,6 @@ char *p; } } } - return 0; } int @@ -3799,6 +4207,56 @@ int *var; return 0; } +static int +ParseNum1000(act, var) +struct action *act; +int *var; +{ + int i; + char *p, **args = act->args; + int dig = 0; + + p = *args; + if (p == 0 || *p == 0 || args[1]) + { + Msg(0, "%s: %s: invalid argument. Give one argument.", + rc_name, comms[act->nr].name); + return -1; + } + i = 0; + while (*p) + { + if (*p >= '0' && *p <= '9') + { + if (dig < 4) + i = 10 * i + (*p - '0'); + else if (dig == 4 && *p >= '5') + i++; + if (dig) + dig++; + } + else if (*p == '.' && !dig) + dig++; + else + { + Msg(0, "%s: %s: invalid argument. Give floating point argument.", + rc_name, comms[act->nr].name); + return -1; + } + p++; + } + if (dig == 0) + i *= 1000; + else + while (dig++ < 4) + i *= 10; + if (i < 0) + i = (int)((unsigned int)~0 >> 1); + debug1("ParseNum1000 got %d\n", i); + *var = i; + return 0; +} + static struct win * WindowByName(s) char *s; @@ -3912,42 +4370,6 @@ char *bname; return 0; } -/* - * Interprets ^?, ^@ and other ^-control-char notation. - * Interprets \ddd octal notation - * - * The result is placed in *cp, p is advanced behind the parsed expression and - * returned. - */ -static char * -ParseChar(p, cp) -char *p, *cp; -{ - if (*p == 0) - return 0; - if (*p == '^' && p[1]) - { - if (*++p == '?') - *cp = '\177'; - else if (*p >= '@') - *cp = Ctrl(*p); - else - return 0; - ++p; - } - else if (*p == '\\' && *++p <= '7' && *p >= '0') - { - *cp = 0; - do - *cp = *cp * 8 + *p - '0'; - while (*++p <= '7' && *p >= '0'); - } - else - *cp = *p++; - return p; -} - - static int IsNum(s, base) register char *s; @@ -4092,13 +4514,17 @@ struct win *wi; /* * Place the window at the head of the most-recently-used list */ - for (pp = &windows; (p = *pp); pp = &p->w_next) - if (p == wi) - break; - ASSERT(p); - *pp = p->w_next; - p->w_next = windows; - windows = p; + if (windows != wi) + { + for (pp = &windows; (p = *pp); pp = &p->w_next) + if (p == wi) + break; + ASSERT(p); + *pp = p->w_next; + p->w_next = windows; + windows = p; + WListLinkChanged(); + } } } } @@ -4208,6 +4634,7 @@ PreviousWindow() static int MoreWindows() { + char *m = "No other window."; if (windows && (fore == 0 || windows->w_next)) return 1; if (fore == 0) @@ -4215,7 +4642,7 @@ MoreWindows() Msg(0, "No window available"); return 0; } - Msg(0, "No other window."+1-1, fore->w_number); /* other arg for nethack */ + Msg(0, m, fore->w_number); /* other arg for nethack */ return 0; } @@ -4259,7 +4686,16 @@ struct win *wi; gotone = 1; } if (gotone) - Activate(-1); + { +#ifdef ZMODEM + if (wi->w_zdisplay == display) + { + D_blocked = 0; + D_readev.condpos = D_readev.condneg = 0; + } +#endif + Activate(-1); + } } FreeWindow(wi); WindowChanged((struct win *)0, 'w'); @@ -4309,6 +4745,7 @@ int where; register char *s, *ss; register struct win **pp, *p; register char *cmd; + int l; s = ss = buf; for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + MAXWIN; pp++) @@ -4321,7 +4758,10 @@ int where; continue; cmd = p->w_title; - if (s - buf + strlen(cmd) > len - 24) + l = strlen(cmd); + if (l > 20) + l = 20; + if (s - buf + l > len - 24) break; if (s > buf || (flags & 4)) { @@ -4341,8 +4781,8 @@ int where; s = AddWindowFlags(s, len, p); } *s++ = ' '; - strcpy(s, cmd); - s += strlen(s); + strncpy(s, cmd, l); + s += l; } *s = 0; return ss; @@ -4510,7 +4950,21 @@ ShowInfo() # endif if (D_CC0 || (D_CS0 && *D_CS0)) { - if (wp->w_gr) + if (wp->w_gr == 2) + { + sprintf(p, " G%c", wp->w_Charset + '0'); + if (wp->w_FontE >= ' ') + p[3] = wp->w_FontE; + else + { + p[3] = '^'; + p[4] = wp->w_FontE ^ 0x40; + p++; + } + p[4] = '['; + p++; + } + else if (wp->w_gr) sprintf(p++, " G%c%c[", wp->w_Charset + '0', wp->w_CharsetR + '0'); else sprintf(p, " G%c[", wp->w_Charset + '0'); @@ -4600,7 +5054,7 @@ char *data; /* dummy */ { ASSERT(display); if (len && fore) - ChangeAKA(fore, buf, 20); + ChangeAKA(fore, buf, strlen(buf)); } static void @@ -4608,7 +5062,7 @@ InputAKA() { char *s, *ss; int n; - Input("Set window's title to: ", 20, INP_COOKED, AKAfin, NULL); + Input("Set window's title to: ", sizeof(fore->w_akabuf) - 1, INP_COOKED, AKAfin, NULL); s = fore->w_title; if (!s) return; @@ -4628,8 +5082,18 @@ char *buf; int len; char *data; /* dummy */ { + char mbuf[256]; if (len) - RcLine(buf); + { + len = strlen(buf) + 1; + if (len > (int)sizeof(mbuf)) + RcLine(buf, len); + else + { + bcopy(buf, mbuf, len); + RcLine(mbuf, sizeof mbuf); + } + } } static void @@ -4840,37 +5304,40 @@ char *fn, **av; * l (left), r (right). placing a mark will now be done with ".". */ int -CompileKeys(s, array) +CompileKeys(s, sl, array) char *s; +int sl; unsigned char *array; { int i; unsigned char key, value; - if (!s || !*s) + if (sl == 0) { for (i = 0; i < 256; i++) array[i] = i; return 0; } debug1("CompileKeys: '%s'\n", s); - while (*s) + while (sl) { - s = ParseChar(s, (char *) &key); - if (!s || *s != '=') + key = *(unsigned char *)s++; + if (*s != '=' || sl < 3) return -1; + sl--; do { - s = ParseChar(++s, (char *) &value); - if (!s) - return -1; + s++; + sl -= 2; + value = *(unsigned char *)s++; array[value] = key; } - while (*s == '='); - if (!*s) + while (*s == '=' && sl >= 2); + if (sl == 0) break; if (*s++ != ':') return -1; + sl--; } return 0; } @@ -4932,7 +5399,7 @@ char *data; /* dummy */ bcopy(D_user->u_plop.buf, pp->buf, D_user->u_plop.len); } pp->len = D_user->u_plop.len; -#ifdef ENCODING +#ifdef ENCODINGS pp->enc = D_user->u_plop.enc; #endif Msg(0, "Copied %d characters into register %c", D_user->u_plop.len, *buf); @@ -5001,6 +5468,7 @@ char *data; /* dummy */ } act.nr = (int)data; act.args = noargs; + act.argl = 0; DoAction(&act, -1); } @@ -5092,7 +5560,7 @@ int len; char *data; { int st; - char salt[2]; + char salt[3]; struct acluser *u = (struct acluser *)data; ASSERT(u); @@ -5117,6 +5585,7 @@ char *data; { for (st = 0; st < 2; st++) salt[st] = 'A' + (int)((time(0) >> 6 * st) % 26); + salt[2] = 0; buf = crypt(u->u_password, salt); bzero(u->u_password, strlen(u->u_password)); free((char *)u->u_password); @@ -5215,11 +5684,11 @@ char *data; /* dummy */ } else { - for (i = 0; i < sizeof(digraphs)/sizeof(*digraphs); i++) + for (i = 0; i < (int)(sizeof(digraphs)/sizeof(*digraphs)); i++) if ((digraphs[i][0] == (unsigned char)buf[0] && digraphs[i][1] == (unsigned char)buf[1]) || (digraphs[i][0] == (unsigned char)buf[1] && digraphs[i][1] == (unsigned char)buf[0])) break; - if (i == sizeof(digraphs)/sizeof(*digraphs)) + if (i == (int)(sizeof(digraphs)/sizeof(*digraphs))) { Msg(0, "Unknown digraph"); return; @@ -5237,7 +5706,7 @@ char *data; /* dummy */ } #ifdef MAPKEYS -static int +int StuffKey(i) int i; { @@ -5258,13 +5727,13 @@ int i; act = 0; #ifdef COPY_PASTE if (InMark() || InInput() || InWList()) - act = &mmtab[i]; + act = i < KMAP_KEYS+KMAP_AKEYS ? &mmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].mm; #endif if ((!act || act->nr == RC_ILLEGAL) && !D_mapdefault) - act = &umtab[i]; + act = i < KMAP_KEYS+KMAP_AKEYS ? &umtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].um; D_mapdefault = 0; if (!act || act->nr == RC_ILLEGAL) - act = &dmtab[i]; + act = i < KMAP_KEYS+KMAP_AKEYS ? &dmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].dm; if (act == 0 || act->nr == RC_ILLEGAL) return -1; DoAction(act, 0); |