www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/01/05/14:49:22

From: "Edison M. Castro" <edison_castro AT ml DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Changing Parent environment
Date: Mon, 5 Jan 1998 14:14:35 -0500
Organization: Merrill Lynch
Lines: 199
Message-ID: <68rbl0$prq$1@news.ml.com>
NNTP-Posting-Host: 165.177.116.168
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

I have some functions written in visual C that change the parent environment
of a program, it make use of some source code found previously in the
internet . I would like for someone to translate it to DJGPP because of its
use of _MK_FP and other Visual C macros

int get_env_index(char *var, char **env_var)
{
/*
 * Find the index into the env_var array of the variable <var>.  If not
 * found, returns the index of the terminating null entry
 */
 register int i;
 char *temp;
 MEMCHECK(temp = (char *)malloc(strlen(var)+2)) ;
 strcpy( temp, var);
 for( i = 0; env_var[i]; i++ ) {
  if(strstr(env_var[i], temp) == env_var[i]) break;
 }
 free(temp);
 return(i);
}

int getenvseg(unsigned *envseg )
{
/*
 * Try to locate the parent environment and fill in the segment address
 * This routine has some OS version dependencies
 * Returns  1  if environment found
 *   0  if environment not found
 */
 unsigned ppsp;
 union _REGS  regs;
 int status ;

 regs.x.ax = 0xD44D;      /* 4dos signature value */
 regs.x.bx = 0;
 _int86(0x2F, &regs, &regs);    /* TSR multiplex interrput */
 ppsp   = regs.x.cx;      /* psp of immediate parent shell */

 if( regs.x.ax == 0x44dd && ppsp == *(unsigned far *)_MK_FP(_psp,0x16) ) {
  /*
   * good, we are running 4dos - AND it is our parent
   * in this case we don't care about dos version
   */
  *envseg =  *(unsigned far *)_MK_FP(ppsp,0x2C);
 } else {
  /*
   * Follow the pointers back to our parent psp and from there get the
   * parent environment segment address
   * With early command.com (pre 3.3) the lowest level shell did not fill
   * in the environment segment (it is 0) but we can still find the
   * environment since it always follows the lowest level shell directly
   */
  ppsp = *(unsigned far *)_MK_FP(_psp,0x16);
  *envseg =  *(unsigned far *)_MK_FP(ppsp,0x2C);
  if ((*envseg == 0) &&
   (_osmajor <= 2 || (_osmajor == 3 && _osminor <= 20))) {
   /*
    * we have the pre 3.3 master command.com - have to assume that the
    * environment segment directly follows the program segment
    * so get the length from the MCB and add it to ppsp
    */
   *envseg = ppsp + *(unsigned far *)_MK_FP(ppsp - 1, 3) + 1;
  }
 }
 /*
  * Verify that the owner of the envseg matches the ppsp we got above
  * - just to be a little paranoid
  */
 if ( *(unsigned far *)_MK_FP((*envseg)-1, 1) != ppsp) {
  *envseg = 0 ;  /* something wrong :-( */
  status  = 0;
 } else {
  status  = 1 ;
 }
 return(status);
}

/* Getting enviroment variable */

unsigned get_env_var(unsigned env_addr, char ***env_var, int *count)
{
/*
 * Copy the parent environment from the segment address given in env_addr,
into
 * the memory block pointed to by env_blk.
 * Extract pointers to the start of each variable and build array env_var.
 * Return the length of the environment block, (bytes, always a multiple of
16)
 */
 static char *env_blk;
 unsigned i, len, offset;
 unsigned seglen;
 struct   _SREGS segregs;
 unsigned _DS;

    _segread( &segregs );
    _DS = segregs.ds;
 seglen = *(unsigned far *)_MK_FP(env_addr - 1, 3) * 16;
 if ((env_blk = (char *)malloc(seglen)) == (char *)NULL)
  fatal ("Cannot allocate memory for environment block", 5);

 _movedata(env_addr, 0, _DS, (unsigned)&env_blk[0], seglen);
 /*
  * make one pass through, counting variables, and allocate space for the
  * env_var array.  Allow for two extra entries - one to add a new variable
  * and a terminating null.
  */
 i = 0; offset = 0;
 do {
  offset += strlen(env_blk+offset) + 1;
  i++;
 } while(*(env_blk+offset));
 MEMCHECK (*env_var = (char **)malloc((i+2)*sizeof(char **))) ;
 *count = i;

 /* load pointers to each of the strings in the array env_var[] */
 i = 0; offset = 0;
 do {
  len = strlen(env_blk+offset);
  (*env_var)[i] = env_blk+offset;
  offset += len+1;
  i++;
 } while(*(env_blk+offset));
 (*env_var)[i] = NULL;    /* terminate with an extra null */
 return (seglen);
}

void put_env_var(unsigned env_addr, unsigned seglen, char **env_var)
{
/*
 * Copy the modified environment from the allocated data area, using the
 * env_var array of pointers, into the memory block pointed to by env_addr.
 */
 char *var_addr;
 unsigned offset, len, i;
 unsigned zero = 0;
 struct   _SREGS segregs;
 unsigned _DS;

    _segread( &segregs );
    _DS = segregs.ds;
 /*
  * Cycle through once to test for environment overflow.  If overflow,
  * nothing is copied to the old environment block
  */
 for( i=0, offset=0, len=0; env_var[i]; offset+=len, i++) {
  len = strlen(env_var[i]) + 1;
  if (offset+len >= seglen-2)  /* overflow */
   fatal ("Environment overflow - not modified\n",4);
 }
 /*
  * Now actually copy the strings
  */
 for( i=0, offset=0, len=0; env_var[i]; offset+=len, i++) {
  len = strlen(env_var[i]) + 1;
  if (len == 1) {
   /* this entry was null - skip it */
   len = 0;
   continue;
  }
  var_addr = env_var[i];
  _movedata(_DS, (unsigned)var_addr, env_addr, offset, len);
 }
 /* stuff a zero word at the end of the environment block */
 _movedata(_DS, (unsigned)&zero, env_addr, offset, sizeof(unsigned));
}

/* Setting enviroment variable */

int set_env_var(char * variable, char * val)
{
 unsigned env_addr, seglen;
 int index, i, count;
 char *value, **env_var;

 if ( !getenvseg(&env_addr))
  fatal ("Cannot locate environment\n",2);

 seglen = get_env_var( env_addr, &env_var, &count );
 index  = get_env_index( variable, env_var );
 if (index == count) env_var[index+1] = (char *)NULL;

  /* set the value of the variable to the rest of the arguments */
 value = (char *) malloc(strlen(variable) + 2);
 strcpy(value,variable);
 strcat(value,"=");
 value = (char *) realloc(value, strlen(value) + strlen(val) + 2);
 strcat(value,val);
 strcpy(value-1,'\0');

 env_var[index] = value;
 put_env_var(env_addr, seglen, env_var);
 return(0);
}




- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019