Adding debian version 3.70~pre8+dfsg-1.
[syslinux-debian/hramrach.git] / gpxe / contrib / romid / setenvs.c
blobe18e399e879e1e468c26db36ca9847ac52464c85
1 /* subroutine to put a value string into an environment symbol.
2 Uses the controling command.com environment, not the programs.
3 This means that the env variable is set so other routines in
4 a .BAT file may use it.
6 call: settheenv (char * symbol, char * val);
7 symbol is an asciiz string containing the env variable name,
8 val is an asciiz string containing the value to assign to this vbl.
10 returns: 0 = OK,
11 1 = failure.
12 failure is not unlikely. The env block may be full. Or on some
13 systems the env block might not be found
15 SETENVS.C was written by Richard Marks <rmarks@KSP.unisys.COM>.
19 #include <stdio.h>
20 #include <dos.h>
21 #include <string.h>
22 #include <stdlib.h>
24 typedef struct {
25 char fill1[0x0A];
26 int *prev_term_handler;
27 int *prev_ctrl_c;
28 int *prev_crit_error;
29 char fill2[0x16];
30 int envir_seg;
31 } psp;
33 typedef struct {
34 char type;
35 int psp_segment;
36 int num_segments;
37 char fill[11];
38 char arena_data;
39 } arena;
42 #define NORMAL_ATYPE 0x4D
43 #define LAST_ATYPE 0x5A
46 static arena * get_next_arena (arena * ap) {
47 return( MK_FP( FP_SEG(ap)+1+ap->num_segments, 0) );
50 /* returns 0 if passed pointer is to an arena, else returns 1 */
51 static int is_valid_arena (arena * ap) {
52 arena * ap1;
53 if (ap->type == NORMAL_ATYPE &&
54 (ap1=get_next_arena(ap))->type == NORMAL_ATYPE &&
55 ( (ap1=get_next_arena(ap1))->type == NORMAL_ATYPE ||
56 ap1->type == LAST_ATYPE) )
57 return(0);
58 return (1);
62 static arena * get_first_arena () {
63 /* return pointer to the first arena.
64 * scan memory for a 0x4D on a segment start,
65 * see if this points to another two levels of arena
67 arena * ap, * ap1;
68 int * temp;
69 int segment;
71 for (segment=0; segment<_CS; segment++) {
72 ap = MK_FP(segment, 0);
73 if ( is_valid_arena (ap) == 0) return (ap);
75 return(NULL);
76 } /* end get_first_arena */
79 static int is_valid_env (char * ad, int num_segs) {
80 char * base_ad;
81 base_ad = ad;
82 while ( (*ad) && (((ad-base_ad)>>4) < num_segs) ) {
83 if (strnicmp(ad, "COMSPEC=", 8)==0) return(0);
84 ad += strlen(ad) + 1;
86 return (1);
90 static arena * get_arena_of_environment () {
91 /* to get the arena of first environment block:
92 First get segment of COMMAND.COM from segment of previous critical err code.
93 Then scan all the arenas for an environment block with a matching PSP
94 segment */
96 arena * ap;
97 psp * pspp, * pspc;
98 unsigned int i, ccseg;
100 /* set pspp to psp of this program */
101 pspp = MK_FP(_psp,0);
103 #ifdef DEBUG
104 printf("prog psp=%p\n",pspp);
105 #endif
107 /* set pspc to psp of COMMAND.COM, back up a bit to get it if needed */
108 ccseg = FP_SEG (pspp->prev_crit_error);
109 if ( (i=ccseg-32) < 60) i=60;
111 while (ccseg>i) {
112 pspc = MK_FP (ccseg, 0);
113 if ( is_valid_arena((arena *) pspc) == 0) goto L1;
114 ccseg--;
116 return (NULL);
118 L1: pspc = MK_FP (++ccseg, 0);
119 #ifdef DEBUG
120 printf("comm.com=%p\n",pspc);
121 #endif
123 /* first see if env seg in command.com points to valid env block
124 if env seg is in a valid arena, then arena must point to this command.com
125 else assume env block is fabricated like for 4DOS, use 128 bytes */
127 ap = MK_FP (pspc->envir_seg-1, 0);
128 i = ap->num_segments;
130 if (is_valid_arena (ap) == 0) {
131 if (ap->psp_segment != FP_SEG(pspc)) goto L2;
132 } else {
133 i = 9;
136 if ( is_valid_env (&ap->arena_data, i) == 0 )
137 return (ap);
139 /* command.com did not so point, search thru all env blocks */
142 if ( (ap=get_first_arena()) != NULL ) {
143 while (ap->type != LAST_ATYPE) {
144 #ifdef DEBUG
145 printf("%p\n",ap);
146 #endif
147 if (ap->psp_segment == FP_SEG(pspc) &&
148 is_valid_env (&ap->arena_data, ap->num_segments)==0 )
149 return (ap);
151 ap = get_next_arena(ap);
153 } return(NULL);
154 } /* end get_arena_of_environment */
156 /*****************************************************************************/
158 int settheenv(char * symbol, char * val) {
159 int total_size,
160 needed_size=0,
161 strlength;
162 char * sp, *op, *envir;
163 char symb_len=strlen(symbol);
164 char found=0;
165 arena * ap;
167 strupr(symbol);
169 /* first, can COMMAND.COM's envir block be found ? */
170 if ( (ap=get_arena_of_environment()) == NULL)
171 return(1);
173 /* search to end of the envir block, get sizes */
174 total_size = 16 * ap->num_segments;
175 envir = &ap->arena_data;
176 op=sp=envir;
177 while (*sp) {
178 strlength = strlen(sp)+1;
179 if ( *(sp+symb_len)=='=' &&
180 strnicmp(sp,symbol,symb_len)==0 )
181 found=1;
182 else {
183 needed_size += strlength;
184 if (found) strcpy(op,sp);
185 op = &op[strlength];
187 sp += strlength;
189 *op=0;
190 if (strlen(val) > 0) {
191 needed_size += 3 + strlen(symbol) + strlen(val);
192 if (needed_size > total_size)
193 return(1); /* could mess with environment expansion here */
195 strcpy(op, symbol); strcat(op, "="); strcat(op, val);
196 op += strlen(op)+1;
197 *op = 0;
199 return(0);
200 } /* end setheenv subroutine */