📄 ckuus5.c
字号:
inidir[i+1] = NUL; break; } } } }}#ifndef NOSPL/* G E T N C M Get next command from current macro definition. Moved to a separate routine in edit 181 to allow multiline GET to work when issued in a macro. Command is copied into string pointed to by argument s, max length n. Returns: 0 if a string was copied, -1 if there was no string to copy.*/intgetncm(s,n) char *s; int n; { int y, /* Character counter */#ifdef COMMENT quote = 0,#endif /* COMMENT */ kp = 0, /* Brace up-down counter */ pp = 0; /* Parenthesis up-down counter */ char *s2; /* Copy of destination pointer */ s2 = s; /* Initialize string pointers */ *s = NUL; /* and destination buffer */ debug(F101,"getncm dest length","",n); for (y = 0; /* Loop for n bytes max */ macp[maclvl] && *macp[maclvl] && y < n; y++, s++, macp[maclvl]++) { *s = *macp[maclvl]; /* Get next char from macro def */ /* debug(F000,"char","",*s); */#ifdef COMMENT/* The intention here was to allow quoting of commas, braces, etc, in macro definitions, e.g. "define rows mode co80\,\%1". And it works, but it breaks just about everything else.*/ if (*s == CMDQ && quote == 0) { /* Allow for quoting of */ quote = 1; /* braces, commas, etc. */ continue; }#endif /* COMMENT *//* Allow braces around macro definition to prevent commas from being turned to end-of-lines and also treat any commas within parens as text so that multiple-argument functions won't cause the command to break prematurely.*/#ifdef COMMENT if (!quote) {#endif /* COMMENT */ if (*s == '{') kp++; /* Count braces */ if (*s == '}') kp--; if (*s == '(') pp++; /* Count parentheses. */ if (*s == ')') pp--; if (*s == ',' && pp <= 0 && kp <= 0) { macp[maclvl]++; /* Comma not in {} or () */ debug(F110,"next cmd",s,0); kp = pp = 0; /* so we have the next command */ break; }#ifdef COMMENT }#endif /* COMMENT */ } /* Reached end. */ if (*s2 == NUL) { /* If nothing was copied, */ debug(F100,"getncm eom","",0); popclvl(); /* pop command level. */ return(-1); } else { /* otherwise, tack CR onto end */ *s++ = CR; *s = '\0'; if (mecho && pflag) /* If MACRO ECHO ON, echo the cmd */ printf("%s\n",s2); debug(F110,"getncm returns ptr to",s2,0); } return(0);}/* D O M A C -- Define and then execute a macro */intdomac(name, def, flags) char *name, *def; int flags; { int x, m; m = maclvl; /* Current macro stack level */ debug(F101,"domac entry maclvl","",maclvl); x = addmac(name, def); /* Define a new macro */ if (x > -1) { /* If successful, */ dodo(x,NULL, flags); /* start it (increments maclvl). */ while (maclvl > m) { /* Keep going till done with it, */ debug(F101,"domac loop maclvl 1","",maclvl); sstate = (CHAR) parser(1); /* parsing & executing each command, */ debug(F101,"domac loop maclvl 2","",maclvl); if (sstate) proto(); /* including protocol commands. */ } debug(F101,"domac loop exit maclvl","",maclvl); } return(success);}#endif /* NOSPL *//* G E T N C T Get next command from TAKE (command) file. Call with: s Pointer to buffer to read into n Length of buffer f File descriptor of file to read from flag 0 == keep line terminator on and allow continuation 1 == discard line terminator and don't allow continuation Call with flag == 0 to read a command from a TAKE file; Call with flag != 0 to read a line from a dialing or network directory. In both cases, trailing comments and/or trailing whitespace is stripped. If flag == 0, continued lines are combined into one line. A continued line is one that ends in hypen or backslash, or any line in a "block", which starts with "{" at the end of a line and ends with "}" at the beginning of a line; blocks may be nested. Returns: 0 if a string was copied, -1 on EOF, -2 on malloc failure -3 if line is not properly terminated -4 if (possibly continued) line is too long. */intgetnct(s,n,f,flag) char *s; int n; FILE *f; int flag; { int i, len, buflen; char c, cc, ccl, *s2, *lp, *lp2, *lp3, *lastcomma = NULL; int bc = 0; /* Block counter */ s2 = s; /* Remember original pointer */ buflen = n; /* Remember original buffer length */ debug(F101,"getnct","",n); if (!(lp2 = (char *) malloc(n+n+1))) { /* Get a temporary buffer */ debug(F101,"getnct malloc failure","",0); return(-2); } while (1) { /* Loop to read lines from file */ if (fgets(lp2,n,f) == NULL) { /* Read a line into lp2 */ debug(F100,"getnct fgets EOF","",0); /* EOF */ free(lp2); /* Free temporary storage */ lp2 = NULL; *s = NUL; /* Make destination be empty */ return(-1); /* Return failure code */ }#ifndef NODIAL if (flag) /* Count this line */ dirline++; else#endif /* NODIAL */ tfline[tlevel]++; len = strlen(lp2) - 1; /* Position of line terminator */ debug(F111,"getnct fgets ok",lp2,len); if (len < 0) len = 0; if (techo && pflag) /* If TAKE ECHO ON, */ printf("%3d. %s", /* echo it this line. */#ifndef NODIAL flag ? dirline :#endif /* NODIAL */ tfline[tlevel], lp2 ); lp3 = lp2; /* Working pointer */ i = len; while (*lp3 == SP || *lp3 == HT) { /* First nonwhitespace character */ i--; lp3++; } if (i == 0 && bc > 0) /* Blank line in {...} block */ continue; /* Isolate, remove, and check terminator */ c = lp2[len]; /* Value of line terminator */ debug(F101,"getnct terminator","",c); if (c < LF || c > CR) { /* It's not a terminator */ debug(F111,"getnct bad line",lp2,c); if (feof(f) && len > 0 && len < n) { /* Kludge Alert... */ printf("Warning: Last line of %s lacks terminator\n", s2 == cmdbuf ? "command file" : "directory file"); c = lp2[++len] = '\n'; /* No big deal - supply one. */ } else { /* Something's wrong, fail. */ free(lp2); lp2 = NULL; return(-3); } } /* Trim trailing whitespace */ for (i = len - 1; i > -1; i--) /* Back up over spaces and tabs */ if (lp2[i] != SP && lp2[i] != HT && lp2[i] != NUL) break; debug(F101,"getnct i","",i); lp2[i+1] = NUL; /* Terminate the string */ debug(F110,"getnct lp2",lp2,0); lp = lp2; /* Make a working pointer */ /* Remove trailing or full-line comment */ while (cc = *lp) { if (cc == ';' || cc == '#') { /* Comment introducer? */ if (lp == lp2) { /* First char on line */ *lp = NUL; break; } else if (*(lp - 1) == SP || *(lp - 1) == HT) { lp--; *lp = NUL; /* Or preceded by whitespace */ break; } } lp++; } if (lp > lp2) lp--; /* Back up over the NUL */ /* Now trim any space that preceded the comment */ while ((*lp == SP || *lp == HT) && lp >= lp2) { *lp = NUL; if (lp <= lp2) break; lp--; } debug(F110,"getnct comment trimmed",lp2,0); len = strlen(lp2); /* Length after trimming */ if (n - len < 2) { /* Check remaining space */ debug(F111,"getnct command too long",s2,buflen); printf("?Line too long, maximum length: %d.\n",buflen); free(lp2); lp2 = NULL; return(-4); } ccl = (len > 0) ? lp2[len-1] : 0; /* Last character in line */ lp = lp2; while (*s++ = *lp++) /* Copy result to target buffer */ n--; /* accounting for length */ s--; /* Back up over the NUL */ /* Check whether this line is continued */ if (flag) /* No line continuation when flag=1 */ break; /* So break out of read-lines loop */ debug(F000,"getnct first char","",*lp3); debug(F000,"getnct last char","",ccl); if (bc > 0 && *lp3 == '}') /* First char on line is '}' */ bc--; /* Decrement block counter */ if (bc == 0 && /* Line is continued if bc > 0 */#ifdef COMMENT /* Not supported as of C-Kermit 6.0 */ ccl != CMDQ && /* or line ends with CMDQ */#endif /* COMMENT */ ccl != '-' && /* or line ends with dash */ ccl != '{') /* or line ends with opening brace */ break; /* None of those, we're done. */ if (ccl == '{') { /* Last char on line is '{'? */ bc++; /* Count the block opener. */ } else if (ccl == '-' /* Explicit continue? */#ifdef COMMENT/* Not supported as of C-Kermit 6.0. */ || ccl == CMDQ#endif /* COMMENT */ ) { s--; /* Yes, back up over terminators */ n++; /* and over continuation character */ } else { /* None of those but (bc > 0) */ lastcomma = s; *s++ = ','; /* and insert a comma */ n--; } debug(F101,"getnct bc","",bc); debug(F100,"getnct continued","",0); } /* read-lines while loop */ if (lastcomma) *lastcomma = SP; if (!flag) /* Tack line terminator back on */ *s++ = c; *s++ = NUL; /* Terminate the string */ untab(s2); /* Done, convert tabs to spaces */ debug(F110,"getnct return",s2,0); free(lp2); /* Free temporary storage */ return(0); /* Return success */}/* P A R S E R -- Top-level interactive command parser. */ /* Call with: m = 0 for normal behavior: keep parsing and executing commands until an action command is parsed, then return with a Kermit start-state as the value of this function. m = 1 to parse only one command, can also be used to call parser() recursively. m = 2 to read but do not execute one command. In all cases, parser() returns: 0 if no Kermit protocol action required > 0 with a Kermit protocol start-state. < 0 upon error.*/intparser(m) int m; { int tfcode, xx, yy, zz; /* Workers */#ifndef NOSPL int inlevel; /* Level we were called at */#endif /* NOSPL */ char *cbp; /* Command buffer pointer */#ifdef MAC extern char *lfiles; /* Fake extern cast */#endif /* MAC */#ifdef AMIGA reqres(); /* restore AmigaDOS requestors */#endif /* AMIGA */#ifdef OS2 if ( cursor_save > -1 ) { /* restore cursor if it was */ cursorena[VCMD] = cursor_save ; /* turned off in file xfer */ cursor_save = -1 ; /* mode */ }#endif /* OS2 */ what = W_COMMAND; /* Now we're parsing commands. */ moving = 0; /* We're not MOVE'ing */ if ( /* If at top (interactive) level ... */#ifndef NOSPL cmdlvl == 0#else tlevel < 0#endif /* NOSPL */ ) concb((char)escape); /* ... put console in 'cbreak' mode. */#ifdef CK_TMPDIR/* If we were cd'd temporarily to another device or directory ... */ if (f_tmpdir) { int x; x = zchdir((char *) savdir); /* ... restore previous directory */ f_tmpdir = 0; /* and remember we did it. */ debug(F111,"parser tmpdir restoring",savdir,x); }#endif /* CK_TMPDIR */#ifndef NOSPL inlevel = cmdlvl; /* Current macro level */ debug(F101,"&parser entry maclvl","",maclvl); debug(F101,"&parser entry inlevel","",inlevel); debug(F101,"&parser entry tlevel","",tlevel); debug(F101,"&parser entry cmdlvl","",cmdlvl); debug(F101,"&parser entry m","",m);#endif /* NOSPL *//* sstate becomes nonzero when a command has been parsed that requires some action from the protocol module. Any non-protocol actions, such as local directory listing or terminal emulation, are invoked directly from below.*/ sstate = 0; /* Start with no start state. */#ifndef NOFRILLS rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */ *optbuf = NUL; /* MAIL and PRINT options */#endif /* NOFRILLS */#ifndef NOSPL query = 0; /* QUERY not active */#endif /* NOSPL */ while (sstate == 0) { /* Parse cmds until action requested */#ifdef WHAT_THE_HECK_IS_THIS int nnn; debug(F100,"top of parse loop","",0); nnn = ttchk(); debug(F101,"APC ttchk p1","",nnn);#endif /* WHAT_THE_HECK_IS_THIS */ remfile = 0; /* Clear these in case REMOTE */ remappd = 0; /* command was interrupted... */ rempipe = 0; /* Take requested action if there was an error in the previous command */#ifndef MAC conint(trap,stptrap); /* In case we were just fg'd */ bgchk(); /* Check background status */#endif /* MAC */ debug(F101,"tlevel","",tlevel);#ifndef NOSPL if (success == 0) { if (cmdstk[cmdlvl].src == CMD_TF && takerr[cmdlvl]) { printf("Command file terminated by error.\n"); popclvl(); if (cmdlvl == 0) return(0); } if (cmdstk[cmdlvl].src == CMD_MD && merror[cmdlvl]) { printf("Command error: macro terminated.\n"); popclvl(); if (m && (cmdlvl < inlevel)) return((int) sstate); } } nulcmd = (m == 2);#else if (success == 0 && tlevel > -1 && takerr[tlevel]) { printf("Command file terminated by error.\n"); popclvl(); cmini(ckxech); /* Clear the cmd buffer. */ if (tlevel < 0) /* Just popped out of cmd files? */ return(0); /* End of init file or whatever. */ }#endif /* NOSPL */#ifdef MAC /* Check for TAKE initiated by menu. */ if ((tlevel == -1) && lfiles) startlfile();#endif /* MAC */ /* If in TAKE file, check for EOF */#ifndef NOSPL#ifdef MAC if#else while#endif /* MAC */ ((cmdstk[cmdlvl].src == CMD_TF) /* If end of take file */ && (tlevel > -1) && feof(tfile[tlevel])) { popclvl(); /* pop command level */ cmini(ckxech); /* and clear the cmd buffer. */ if (cmdlvl == 0) { /* Just popped out of all cmd files? */ if (#ifdef NT StartedFromDialer &&#endif /* NT */ cfilef) { /* Delete startup file? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -