📄 setenvs.c
字号:
/* subroutine to put a value string into an environment symbol. Uses the controling command.com environment, not the programs. This means that the env variable is set so other routines in a .BAT file may use it. call: settheenv (char * symbol, char * val); symbol is an asciiz string containing the env variable name, val is an asciiz string containing the value to assign to this vbl. returns: 0 = OK, 1 = failure. failure is not unlikely. The env block may be full. Or on some systems the env block might not be found SETENVS.C was written by Richard Marks <rmarks@KSP.unisys.COM>.*/#include <stdio.h>#include <dos.h>#include <string.h>#include <stdlib.h>typedef struct { char fill1[0x0A]; int *prev_term_handler; int *prev_ctrl_c; int *prev_crit_error; char fill2[0x16]; int envir_seg;} psp;typedef struct { char type; int psp_segment; int num_segments; char fill[11]; char arena_data;} arena;#define NORMAL_ATYPE 0x4D#define LAST_ATYPE 0x5Astatic arena * get_next_arena (arena * ap) { return( MK_FP( FP_SEG(ap)+1+ap->num_segments, 0) );}/* returns 0 if passed pointer is to an arena, else returns 1 */static int is_valid_arena (arena * ap) { arena * ap1; if (ap->type == NORMAL_ATYPE && (ap1=get_next_arena(ap))->type == NORMAL_ATYPE && ( (ap1=get_next_arena(ap1))->type == NORMAL_ATYPE || ap1->type == LAST_ATYPE) ) return(0); return (1);}static arena * get_first_arena () {/* return pointer to the first arena. * scan memory for a 0x4D on a segment start, * see if this points to another two levels of arena */ arena * ap, * ap1; int * temp; int segment; for (segment=0; segment<_CS; segment++) { ap = MK_FP(segment, 0); if ( is_valid_arena (ap) == 0) return (ap); } return(NULL);} /* end get_first_arena */static int is_valid_env (char * ad, int num_segs) { char * base_ad; base_ad = ad; while ( (*ad) && (((ad-base_ad)>>4) < num_segs) ) { if (strnicmp(ad, "COMSPEC=", 8)==0) return(0); ad += strlen(ad) + 1; } return (1);}static arena * get_arena_of_environment () {/* to get the arena of first environment block: First get segment of COMMAND.COM from segment of previous critical err code. Then scan all the arenas for an environment block with a matching PSP segment */arena * ap;psp * pspp, * pspc;unsigned int i, ccseg;/* set pspp to psp of this program */pspp = MK_FP(_psp,0);#ifdef DEBUGprintf("prog psp=%p\n",pspp);#endif/* set pspc to psp of COMMAND.COM, back up a bit to get it if needed */ccseg = FP_SEG (pspp->prev_crit_error);if ( (i=ccseg-32) < 60) i=60;while (ccseg>i) { pspc = MK_FP (ccseg, 0); if ( is_valid_arena((arena *) pspc) == 0) goto L1; ccseg--;}return (NULL);L1: pspc = MK_FP (++ccseg, 0);#ifdef DEBUGprintf("comm.com=%p\n",pspc);#endif/* first see if env seg in command.com points to valid env block if env seg is in a valid arena, then arena must point to this command.com else assume env block is fabricated like for 4DOS, use 128 bytes */ap = MK_FP (pspc->envir_seg-1, 0);i = ap->num_segments;if (is_valid_arena (ap) == 0) { if (ap->psp_segment != FP_SEG(pspc)) goto L2;} else { i = 9;}if ( is_valid_env (&ap->arena_data, i) == 0 ) return (ap);/* command.com did not so point, search thru all env blocks */L2:if ( (ap=get_first_arena()) != NULL ) { while (ap->type != LAST_ATYPE) {#ifdef DEBUG printf("%p\n",ap);#endif if (ap->psp_segment == FP_SEG(pspc) && is_valid_env (&ap->arena_data, ap->num_segments)==0 ) return (ap); ap = get_next_arena(ap); }} return(NULL);} /* end get_arena_of_environment *//*****************************************************************************/int settheenv(char * symbol, char * val) {int total_size, needed_size=0, strlength;char * sp, *op, *envir;char symb_len=strlen(symbol);char found=0;arena * ap;strupr(symbol);/* first, can COMMAND.COM's envir block be found ? */if ( (ap=get_arena_of_environment()) == NULL) return(1);/* search to end of the envir block, get sizes */total_size = 16 * ap->num_segments;envir = &ap->arena_data;op=sp=envir;while (*sp) { strlength = strlen(sp)+1; if ( *(sp+symb_len)=='=' && strnicmp(sp,symbol,symb_len)==0 ) found=1; else { needed_size += strlength; if (found) strcpy(op,sp); op = &op[strlength]; } sp += strlength;}*op=0;if (strlen(val) > 0) { needed_size += 3 + strlen(symbol) + strlen(val); if (needed_size > total_size) return(1); /* could mess with environment expansion here */ strcpy(op, symbol); strcat(op, "="); strcat(op, val); op += strlen(op)+1; *op = 0;}return(0);} /* end setheenv subroutine */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -