123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /* 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 0x5A
-
-
- static 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 DEBUG
- printf("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 DEBUG
- printf("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 */
|