⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ckuus5.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	tlevel = 0;	if (tfnam[tlevel] = malloc(strlen(line)+1))	  strcpy(tfnam[tlevel],line);#ifndef NOSPL	cmdlvl++;	ifcmd[cmdlvl] = 0;	iftest[cmdlvl] = 0;	count[cmdlvl] = 0;	debug(F101,"open ok","",cmdlvl);	cmdstk[cmdlvl].src = CMD_TF;	cmdstk[cmdlvl].lvl = tlevel;#endif /* NOSPL */	debug(F110,"init file",line,0);    }    if (homdir && (tlevel < 0)) {    	strcpy(lp,kermrc);	if ((tfile[0] = fopen(line,"r")) != NULL) {	    tlevel = 0;	if (tfnam[tlevel] = malloc(strlen(line)+1))	  strcpy(tfnam[tlevel],line);#ifndef NOSPL	    cmdlvl++;	    cmdstk[cmdlvl].src = CMD_TF;	    cmdstk[cmdlvl].lvl = tlevel;	    ifcmd[cmdlvl] = 0;	    iftest[cmdlvl] = 0;	    count[cmdlvl] = 0;#endif /* NOSPL */	}    }#endif /* OS2 */#ifdef AMIGA    reqpop();				/* Restore requestors */#endif /* AMIGA */}#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, kp = 0, pp = 0;    char *s2;        s2 = s;    *s = NUL;				/* Copy next cmd to command buffer. */        debug(F111,"getncm",s,n);    for (y = 0; 	 macp[maclvl] && *macp[maclvl] && y < n;	 y++, s++, macp[maclvl]++) {		*s = *macp[maclvl];		/* Get next character */	debug(F000,"char","",*s);/*  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.*/	if (*s == '{') kp++;		/* Count braces */	if (*s == '}') kp--;	if (*s == '(') pp++;		/* Count parentheses. */	if (*s == ')') pp--;	if (*s == ',' && pp <= 0 && kp <= 0) {	    macp[maclvl]++;	    debug(F110,"next cmd",s,0);	    kp = pp = 0;	    break;	}    }					/* 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)	  printf("%s\n",s2);	debug(F101,"getncm returns ptr to",s2,0);    }    return(0);}#endif /* NOSPL *//*  G E T N C T  Get next command from current TAKE file.  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 on EOF,  -2 on malloc failure  -3 if line not properly terminated*/intgetnct(s,n) char *s; int n; {    int i, j;    char c, *s2, *lp, *lp2;    s2 = s;				/* Remember original pointer */    debug(F101,"getnct","",n);    if (!(lp2 = (char *) malloc(n+1))) { /* Get a temporary buffer */	debug(F101,"getnct malloc failure","",0);	return(-2);    }    lp = lp2;				/* Make a working pointer */					/* (lp2 must not change!) */    while (1) {				/* Loop to read lines from file */    	if (fgets(lp2,n,tfile[tlevel]) == NULL) { /* EOF */	    free(lp2);			/* Free temporary storage */	    *s = NUL;			/* Make destination be empty */	    return(-1);			/* Return failure code */	}	debug(F110,"Line from TAKE file",lp2,0); /* Got a line */	if (techo && pflag)		/* If TAKE ECHO ON, */	  printf("%s",lp2);		/* echo it. */	lp = lp2;			/* Make a working pointer *//* Trim trailing whitespace */	j = strlen(lp2) - 1;		/* Position of line terminator */	if (j < 0) j = 0;	c = lp2[j];			/* Value of line terminator */	if (c < LF || c > CR) {		/* It's not a terminator */	    debug(F111,"getnct bad line",lp2,c);	    if (feof(tfile[tlevel]) && j > 0 && j < n) {		printf("Warning: Last line of TAKE file lacks terminator\n");		c = lp2[++j] = '\n';	    } else return(-3);	}	for (i = j - 1; i > -1; i--)	/* Back up over spaces and tabs */	  if (lp2[i] != SP && lp2[i] != HT && lp2[i] != NUL)	    break;	lp2[i+1] = c;			/* Move after last nonblank char */	lp2[i+2] = NUL;			/* Terminate the string */	while (*s++ = *lp++) {		/* Copy result to target buffer */	    if (--n < 2) {		printf("?Command too long, maximum length: %d.\n",CMDBL);		free(lp2);		return(dostop());	    }/* Check for trailing comment, " ;" or " #" */	    if ((s > s2 + 1) &&		(*(s-1) == ';' || *(s-1) == '#') &&		(*(s-2) == SP  || *(s-2) == HT)) {		debug(F100,"Trailing comment","",0);		s -= 2;			/* Got one, back up buffer pointer */		n += 2;			/* and adjust free space count. */		while ((s >= s2)	/* Trim whitespace again. */		       && (*s == SP || *s == HT))		  s--, n++;		s++;			/* Point after last character */		*s++ = c;		/* Put back line terminator */		*s++ = NUL;		/* and string terminator */		n -= 3;			/* Adjust free count */		debug(F110,"Comment trimmed & terminated",s2,0);		break;	    }	}/* Check whether this line is continued */	debug(F000,"Last char in line","",*(s-3));	if (*(s - 3) != CMDQ && *(s - 3) != '-') /* Line continued? */	  break;				 /* No, done. */	s -= 3;					 /* No, back up pointer */	debug(F100,"Got continue char","",0);	 /* and continue */    }    untab(s2);				/* Done, convert tabs to spaces */    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 */    what = W_COMMAND;		/* Now we're parsing commands. */#ifndef NOSPL    if (cmdlvl == 0)		/* If at top (interactive) level, */#else    if (tlevel < 0)#endif /* NOSPL */      concb((char)escape);	/* put console in cbreak mode. */#ifndef NOSPL    ifcmd[0] = 0;		/* Command-level related variables */    iftest[0] = 0;		/* initialize variables at top level */    count[0] = 0;		/* of stack... */    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.*/#ifdef COMMENT    if (local && pflag)			/* Just returned from connect? */      printf("\n");#endif /* COMMENT */    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 */    while (sstate == 0) {		/* Parse cmds until action requested */	debug(F100,"top of parse loop","",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				/* In case we just reached top level */	debug(F101,"cmdlvl","",cmdlvl);	if (cmdlvl == 0) concb((char)escape);#else	if (tlevel < 0) concb((char)escape);#endif /* NOSPL */#ifndef NOSPL	if (success == 0) {	    if (cmdstk[cmdlvl].src == CMD_TF && terror) {		printf("Command error: take file terminated.\n");		popclvl();		if (cmdlvl == 0) return(0);	    }	    if (cmdstk[cmdlvl].src == CMD_MD && merror) {		printf("Command error: macro terminated.\n");		popclvl();		if (m && (cmdlvl < inlevel))		  return((int) sstate);	    }	}	nulcmd = (m == 2);#else	if (success == 0 && tlevel > -1 && terror) {	    printf("Command error: take file terminated.\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? */	      return(0);		/* End of init file or whatever. */ 	}#ifdef MAC	miniparser(1);	if (sstate == 'a') {		/* if cmd-. cancel */	    debug(F100, "parser: cancel take due to sstate", "", sstate);	    sstate = '\0';	    dostop();	    return(0);			/* End of init file or whatever. */	}#endif /*  MAC */#else /* NOSPL */	if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */	    popclvl();			/* Pop up one level. */	    cmini(ckxech);		/* and clear the cmd buffer. */	    if (tlevel < 0) 		/* Just popped out of cmd files? */	      return(0);		/* End of init file or whatever. */ 	}#endif /* NOSPL */#ifndef NOSPL        if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */	    debug(F100,"parser macro","",0);	    maclvl = cmdstk[cmdlvl].lvl; /* Get current level */	    debug(F101,"parser maclvl","",maclvl);	    cbp = cmdbuf;		/* Copy next cmd to command buffer. */	    *cbp = NUL;	    if (*savbuf) {		/* In case then-part of 'if' command */		strcpy(cbp,savbuf);	/* was saved, restore it. */		*savbuf = '\0';	    } else {			/* Else get next cmd from macro def */		if (getncm(cbp,CMDBL) < 0) {		    if (m && (cmdlvl < inlevel))		      return((int) sstate);		    else /* if (!m) */ continue;		}	    }	    debug(F110,"cmdbuf from macro",cmdbuf,0);	} else if (cmdstk[cmdlvl].src == CMD_TF)#else	  if (tlevel > -1)  #endif /* NOSPL */	  {#ifndef NOSPL	    if (*savbuf) {		/* In case THEN-part of IF command */		strcpy(cmdbuf,savbuf);	/* was saved, restore it. */		*savbuf = '\0';	    } else#endif /* NOSPL */	      /* Get next line from TAKE file */	      if ((tfcode = getnct(cmdbuf,CMDBL)) < 0) {		  if (tfcode < -1) {	/* Error */		      printf("?Error in TAKE command file: %s\n",			     (tfcode == -2) ? "Memory allocation failure" :			     "Line too long or contains NUL characters"			     );		      popclvl();		  }		  continue;		/* -1 means EOF */	      }	            /* If interactive, get next command from user. */	} else {			/* User types it in. */	    if (pflag) prompt(xxstring);	    cmini(ckxech);    	}        /* Now know where next command is coming from. Parse and execute it. */	repars = 1;			/* 1 = command needs parsing */	displa = 0;			/* Assume no file transfer display */	while (repars) {		/* Parse this cmd until entered. */	    debug(F101,"parser top of while loop","",0);	    cmres();			/* Reset buffer pointers. */	    xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring);	    debug(F101,"top-level cmkey2","",xx);	    if (xx == -5) {		yy = chktok(toktab);		debug(F101,"top-level cmkey token","",yy);		ungword();		switch (yy) {#ifndef NOPUSH		  case '!': xx = XXSHE; break; /* Shell escape */#endif /* NOPUSH */		  case '#': xx = XXCOM; break; /* Comment */		  case ';': xx = XXCOM; break; /* Comment */#ifndef NOSPL		  case ':': xx = XXLBL; break; /* GOTO label */#endif /* NOSPL */#ifndef NOPUSH                  case '@': xx = XXSHE; break; /* Shell (DCL) escape */#endif /* NOPUSH */		  default: 		    printf("\n?Invalid - %s\n",cmdbuf);		    xx = -2;		}	    }#ifndef NOSPL            /* Special handling for IF..ELSE */	    if (ifcmd[cmdlvl])		/* Count stmts after IF */	      ifcmd[cmdlvl]++;	    if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM)	      ifcmd[cmdlvl] = 0;	    /* Execute the command and take action based on return code. */	    if (nulcmd) {		/* Ignoring this command? */		xx = XXCOM;		/* Make this command a comment. */	    }#endif /* NOSPL */	    zz = docmd(xx);	/* Parse rest of command & execute. */	    debug(F101,"docmd returns","",zz);#ifdef MAC	    if (tlevel > -1) {		if (sstate == 'a') {	/* if cmd-. cancel */		    debug(F110, "parser: cancel take, sstate:", "a", 0);		    sstate = '\0';		    dostop();		    return(0);		/* End of init file or whatever. */		}	    }#endif /* MAC */	    switch (zz) {		case -4:		/* EOF (e.g. on redirected stdin) */		    doexit(GOOD_EXIT,xitsta); /* ...exit successfully */	        case -1:		/* Reparse needed */		    repars = 1;		/* Just set reparse flag and  */		    continue;		case -6:		/* Invalid command given w/no args */	    	case -2:		/* Invalid command given w/args */#ifdef COMMENT#ifndef NOSPL		    /* This is going to be really ugly... */		    yy = mlook(mactab,atmbuf,nmac); /* Look in macro table */		    if (yy > -1) {	            /* If it's there */			if (zz == -2) {	            /* insert "do" */			    char *mp;			    mp = malloc((int)strlen(cmdbuf) + 5);			    if (!mp) {				printf("?malloc error 1\n");				return(-2);			    }			    sprintf(mp,"do %s ",cmdbuf);			    strcpy(cmdbuf,mp);			    free(mp);			} else sprintf(cmdbuf,"do %s %c",atmbuf, CR);			if (ifcmd[cmdlvl] == 2)	/* This one doesn't count! */			  ifcmd[cmdlvl]--;			debug(F111,"stuff cmdbuf",cmdbuf,zz);			repars = 1;	/* go for reparse */			continue;		    } else {			char *p;			int n;			p = cmdbuf;			lp = line;     			n = LINBUFSIZ;			if (cmflgs == 0) printf("\n");			if (xxstring(p,&lp,&n) > -1) 			  printf("?Invalid: %s\n",line);			else			  printf("?Invalid: %s\n",cmdbuf);		    } /* (fall thru...) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -