static int do_echo(char *param, void (*fct)(unsigned,...)) { int status; if(param && *param) { status = isspace(*param); /* Unlike other internal commands, puncation characters are not removed by ECHO */ param = ltrimsp(param + 1); } else status = 1; switch(onoffStr(param)) { case OO_On: gflag_echo = 1; goto chkGFlgPrompt; case OO_Off: gflag_echo = 0; chkGFlgPrompt: if(!gflag_batchlevel) gflag_dispPrompt = gflag_echo; break; case OO_Null: case OO_Empty: default: if(status) { fct(TEXT_MSG_ECHO_STATE, gflag_echo ? D_ON : D_OFF); break; } /**FALL THROUGH**/ param = ""; case OO_Other: fct(TEXT_ECHO, param); } return 0; }
char *nls_maketime(int mode, int hour, int minute, int second, int fraction) { char buf[4 + 4 + sizeof(int) * 8 * 4 + 6]; char *p, *q; int i, pm; #ifdef FEATURE_NLS refreshNLS(); #define fmt nlsBuf->timefmt #define sep nlsBuf->timeSep #define dsep nlsBuf->decimalSep #else #define fmt 0 #define sep ":" #define dsep "." #endif /** Warning: condition always true -- if !NLS **/ if(fmt == 0) { /* 12hour display */ if((pm = hour >= 12) != 0) { hour -= 12; } if(hour == 0) hour = 12; i = sprintf(p = buf, "%2u%s%02u", hour, sep, minute); } else { /** Warning: unreachable code -- if !defined(NLS) **/ i = sprintf(p = buf, "%02u%s%02u", hour, sep, minute); } if(i == EOF) return 0; if(second >= 0) { i = sprintf(p += i, "%s%02u", sep, second); if(i == EOF) return 0; if(fraction) { i = sprintf(p += i, "%s%u", dsep, fraction); if(i == EOF) return 0; } } /** Warning: conditional always true -- if !NLS **/ if(fmt == 0) { q = getString(pm? TEXT_STRING_PM: TEXT_STRING_AM); if(!q) return 0; if(mode & NLS_MAKE_SHORT_AMPM) { *(p += i) = *ltrimsp(q); p[1] = 0; } else strcpy(p + i, q); } return strdup(buf); }
int parsetime(const char *s, struct dostime_t * const timep) { struct dostime_t t; int nums[4], items; int pm; assert(s); memset(nums, 0, sizeof(nums)); /* let default everything to zero */ /* Parse at maximum three numbers */ s = parsenum(s, 4, &items, nums); if (!s) /* general error */ return E_Syntax; /* 12 hour time format? */ pm = 0; /* no such flag */ switch(toupper(*s)) { case 'P': ++pm; /* post meridian */ case 'A': ++pm; /* ante meridian */ /* strip ?M or ?.M. */ if(toupper(s[1]) == 'M') s += 2; else if(memicmp(s + 1, ".M.", 3) == 0) s += 4; } if(*ltrimsp(s)) return E_Syntax; /* too many characters on line */ switch (items) { case 0: /* empty line --> always OK */ return E_Empty; case 1: /* single number --> error */ return E_Useage; #if 0 default: /* four numbers --> 1/100s, s, min, h */ /* else: 1/100s and/or s default to zero */ break; #endif } t.hour = nums[0]; t.minute = nums[1]; t.second = nums[2]; /* if missing defaults to previously set */ t.hsecond = nums[3]; /* values, aka 0 */ switch (pm) { case 2: /* post meridian */ if(t.hour != 12) t.hour += 12; break; case 1: /* antes meridian */ if (t.hour == 12) t.hour = 0; break; /* default: not specified --> nothing to do */ } if (t.hour >= 24 || t.minute >= 60 || t.second >= 60 || t.hsecond > 99) return E_Range; if(timep) memcpy(timep, &t, sizeof(t)); return E_None; }
static void docommand(char *line) { /* * look through the internal commands and determine whether or not this * command is one of them. If it is, call the command. If not, call * execute to run it as an external program. * * line - the command line of the program to run */ #ifdef FEATURE_INSTALLABLE_COMMANDS /* Duplicate the command line into such buffer in order to allow Installable Commands to alter the command line. *line cannot be modified as pipes would be destroyed. */ /* Place both buffers immediately following each other in order to make sure the contents of args can be appended to com without any buffer overflow checks. *2 -> one buffer for com and one for args +2 -> max length byte of com + cur length of com +3 -> max length byte of args + cur length of args + additional '\0' */ char buf[2+2*BUFFER_SIZE_MUX_AE+2+1]; #define com (buf + 2) #define args (buf + 2 + BUFFER_SIZE_MUX_AE + 2) #define BUFFER_SIZE BUFFER_SIZE_MUX_AE #else char com[MAX_INTERNAL_COMMAND_SIZE]; #define BUFFER_SIZE MAX_INTERNAL_COMMAND_SIZE #endif char *cp; char *rest; /* pointer to the rest of the command line */ struct CMD *cmdptr; assert(line); /* delete leading spaces, but keep trailing whitespaces */ line = ltrimcl(line); #ifdef FEATURE_INSTALLABLE_COMMANDS #if BUFFER_SIZE < MAX_INTERNAL_COMMAND_SIZE if(strlen(line) > BUFFER_SIZE) { error_line_too_long(); return; } #endif line = strcpy(args, line); #endif if (*(rest = line)) /* Anything to do ? */ { cp = com; /* Copy over 1st word as lower case */ /* Internal commands are constructed out of non-delimiter characters; ? had been parsed already */ while(*rest && is_fnchar(*rest) && !strchr(QUOTE_STR, *rest)) *cp++ = toupper(*rest++); if(*rest && strchr(QUOTE_STR, *rest)) /* If the first word is quoted, it is no internal command */ cp = com; /* invalidate it */ *cp = '\0'; /* Terminate first word */ if(*com) { #ifdef FEATURE_INSTALLABLE_COMMANDS /* Check for installed COMMAND extension */ if(runExtension(com, args)) return; /* OK, executed! */ dprintf( ("[Command on return of Installable Commands check: >%s<]\n", com) ); #endif /* Scan internal command table */ for (cmdptr = internalCommands ; cmdptr->name && strcmp(com, cmdptr->name) != 0 ; cmdptr++); } if(*com && cmdptr->name) { /* internal command found */ switch(cmdptr->flags & (CMD_SPECIAL_ALL | CMD_SPECIAL_DIR)) { case CMD_SPECIAL_ALL: /* pass everything into command */ break; case CMD_SPECIAL_DIR: /* pass '\\' & '.' too */ if(*rest == '\\' || *rest == '.' || *rest == ':') break; default: /* pass '/', ignore ',', ';' & '=' */ if(!*rest || *rest == '/') break; if(isargdelim(*rest)) { rest = ltrimcl(rest); break; } /* else syntax error */ error_syntax(0); return; } /* JPP this will print help for any command */ if (strstr(rest, "/?")) { displayString(cmdptr->help_id); } else { dprintf(("CMD '%s' : '%s'\n", com, rest)); cmdptr->func(rest); } } else { #ifdef FEATURE_INSTALLABLE_COMMANDS if(*com) { /* external command */ /* Installable Commands are allowed to change both: "com" and "args". Therefore, we may need to reconstruct the external command line */ /* Because com and *rest are located within the very same buffer and rest is definitely terminated with '\0', the followinf memmove() operation is fully robust against buffer overflows */ memmove(com + strlen(com), rest, strlen(rest) + 1); /* Unsave, but probably more efficient operation: strcat(com, rest); -- 2000/12/10 ska*/ line = com; } #endif /* no internal command --> spawn an external one */ cp = unquote(line, rest = skip_word(line)); if(!cp) { error_out_of_memory(); return; } execute(cp, ltrimsp(rest)); free(cp); } } #undef line #undef com #undef args #undef BUFFER_SIZE }
char *trimsp(char *str) { assert(str); rtrimsp(str); return ltrimsp(str); }