home *** CD-ROM | disk | FTP | other *** search
- /* This is file STUBEDIT.C */
- /*
- ** Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.dj", available from DJ Delorie at the address above.
- ** A copy of "copying.dj" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.dj".
- **
- ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <io.h>
- #include <fcntl.h>
-
- #include "gotypes.h"
- #include "stubinfo.h"
-
- word32 offset_of_info = 0;
- word32 size_of_info = 0;
-
- StubInfo stub_info = {
- STUB_INFO_MAGIC
- };
-
- char *key = stub_info.magic;
-
- void find_info(char *filename)
- {
- FILE *f;
- int ch, found = 0;
- int key_p;
- long key_max, key_cnt=0;
- unsigned char header[6];
- unsigned char test_magic[16];
-
- f = fopen(filename, "rb");
- if (f == 0)
- {
- char buf[100];
- sprintf(buf, "Fatal error in stubedit reading %s", filename);
- perror(buf);
- exit(1);
- }
-
- fread(header, 6, 1, f);
- key_max = header[4] + header[5]*256 + 1;
- key_max *= 512;
-
- /* First, look for tag */
- fseek(f, -4L, 2);
- fread(test_magic, 4, 1, f);
- offset_of_info = (test_magic[0])
- | (test_magic[1] << 8)
- | (test_magic[2] << 16)
- | (test_magic[3] << 24);
- if (offset_of_info > 0 && offset_of_info < key_max)
- {
- fseek(f, offset_of_info, 0);
- fread(test_magic, 16, 1, f);
- if (strcmp((char *)test_magic, key) == 0)
- found = 1;
- }
-
- if (!found)
- {
- fseek(f, 0L, 0);
- key_p = 0;
- while ((ch = fgetc(f)) != EOF)
- {
- if (ch == key[key_p])
- {
- key_p++;
- if (key[key_p] == 0)
- {
- fgetc(f); /* the NULL */
- offset_of_info = ftell(f) - 16; /* skip the NULL in the file */
- found = 1;
- break;
- }
- }
- else
- key_p = 0;
- key_cnt++;
- if (key_cnt > key_max)
- break;
- }
- }
- if (!found)
- {
- fprintf(stderr, "Error: I cannot find the stub info structure. Must be either\n");
- fprintf(stderr, "this is not a stub'd program, or it is older and does not have one.\n");
- exit(1);
- }
-
- fseek(f, offset_of_info + 16L, 0);
- fread(&size_of_info, 1, 4, f);
- stub_info.struct_length = size_of_info;
- if (size_of_info > sizeof(StubInfo))
- size_of_info = sizeof(StubInfo);
- fseek(f, offset_of_info, 0);
- fread(&stub_info, 1, (int)size_of_info, f);
- fclose(f);
- return;
- }
-
- void store_info(char *filename)
- {
- FILE *f;
- f = fopen(filename, "r+b");
- if (f == 0)
- {
- char buf[100];
- sprintf(buf, "Fatal error in stubedit writing %s", filename);
- perror(buf);
- exit(1);
- }
- fseek(f, offset_of_info, 0);
- fwrite(&stub_info, 1, (int)size_of_info, f);
- fclose(f);
- }
-
- char *pose_question(char *question, char *default_answer)
- {
- static char response[200];
- printf("%s ? [%s] ", question, default_answer);
- fflush(stdout);
- gets(response);
- if (response[0] == '\0')
- return 0;
- return response;
- }
-
- typedef void (*PerFunc)(void *address_of_field, char *buffer);
-
- void str_v2s(void *addr, char *buf)
- {
- if (*(char *)addr == 0)
- strcpy(buf, "\"\"");
- else
- {
- strncpy(buf, (char *)addr, 14);
- buf[14] = 0;
- }
- }
-
- void str_s2v(void *addr, char *buf)
- {
- if (strcmp(buf, "\"\"") == 0)
- *(char *)addr = 0;
- else
- {
- strncpy((char *)addr, buf, 14);
- ((char *)addr)[14] = 0;
- }
- }
-
- void bool_v2s(void *addr, char *buf)
- {
- if (*(word8 *)addr)
- strcpy(buf, "yes");
- else
- strcpy(buf, "no");
- }
-
- void bool_s2v(void *addr, char *buf)
- {
- switch (buf[0])
- {
- case 'y':
- case 'Y':
- case '1':
- case 't':
- case 'T':
- *(char *)addr = 1;
- break;
- case 'n':
- case 'N':
- case '0':
- case 'f':
- case 'F':
- *(char *)addr = 0;
- break;
- }
- }
-
- void ver_v2s(void *addr, char *buf)
- {
- char *field = (char *)(addr);
- char *rtype = "unknown";
- char *fmt = "%d.%d.%s%d";
- switch (field[1])
- {
- case 'a':
- rtype = "alpha";
- break;
- case 'b':
- rtype = "beta";
- break;
- case 'f':
- fmt = "%d.%d";
- break;
- case 'm':
- rtype = "maint";
- break;
- }
- sprintf(buf, fmt, field[3], field[2], rtype, field[0]);
- }
-
- void ver_s2v(void *addr, char *buf)
- {
- char *field = (char *)(addr);
- int major = 0;
- int minor = 0;
- char rtype;
- int release = 0;
- char rstr[100];
- rstr[0] = 'f';
- sscanf(buf, "%d.%d.%[^0-9]%d", &major, &minor, &rstr, &release);
- rtype = rstr[0];
- field[3] = major;
- field[2] = minor;
- field[1] = rtype;
- field[0] = release;
- }
-
- void num_v2s(void *addr, char *buf)
- {
- word32 v = *(word32 *)addr;
- sprintf(buf, "%#lx (%dk)", v, v / 1024L);
- }
-
- void num_s2v(void *addr, char *buf)
- {
- word32 r = 0;
- char s = 0;
- sscanf(buf, "%i%c", &r, &s);
- switch (s)
- {
- case 'k':
- case 'K':
- r *= 1024L;
- break;
- case 'm':
- case 'M':
- r *= 1048576L;
- break;
- }
- *(word32 *)addr = r;
- }
-
- struct {
- char *short_name;
- char *long_name;
- void *addr_of_field;
- PerFunc val2string;
- PerFunc string2val;
- } per_field[] = {
- { "extender",
- "Name of program to run as the extender (max 13 chars)",
- stub_info.go32,
- str_v2s, str_s2v
- },
- { "version",
- "Version of GO32 required to run this program",
- stub_info.required_go32_version,
- ver_v2s, ver_s2v
- },
- {
- "minstack",
- "Minimum amount of stack space (bytes/K/M)",
- (void *)(&stub_info.min_stack),
- num_v2s, num_s2v
- },
- {
- "keepmem",
- "Maximum amount of virtual memory to keep when spawning",
- (void *)(&stub_info.max_keep_on_spawn),
- num_v2s, num_s2v
- },
- {
- "runfile",
- "Base name of file to actually run (max 13 chars, \"\"=self)",
- (void *)(&stub_info.actual_file_to_run),
- str_v2s, str_s2v
- },
- {
- "globbing",
- "Enable command-line wildcard expansion (yes/no)",
- (void *)(&stub_info.enable_globbing),
- bool_v2s, bool_s2v,
- },
- {
- "availmem",
- "Amount of conventional memory to leave (bytes/K/M)",
- (void *)(&stub_info.free_conventional_memory),
- num_v2s, num_s2v
- },
- };
-
- #define NUM_FIELDS (sizeof(per_field) / sizeof(per_field[0]))
-
- #define HFORMAT "%-16s %s\n"
-
- void give_help(void)
- {
- int i;
- fprintf(stderr, "Usage: stubedit [-v] [-h] filename.exe [field=value . . . ]\n");
- fprintf(stderr, "-h = give help -v = view info field=value means set w/o prompt\n");
- fprintf(stderr, HFORMAT, "-field-", "-description-");
-
- for (i=0; i < NUM_FIELDS; i++)
- fprintf(stderr, HFORMAT, per_field[i].short_name, per_field[i].long_name);
- exit(1);
- }
-
- main(int argc, char **argv)
- {
- int view_only = 0;
- int i;
- int need_to_save;
-
- if (argc > 1 && strcmp(argv[1], "-h") == 0)
- give_help();
-
- if (argc > 1 && strcmp(argv[1], "-v") == 0)
- {
- view_only = 1;
- argc--;
- argv++;
- }
-
- if (argc < 2)
- give_help();
-
- find_info(argv[1]);
-
- if (view_only)
- {
- char buf[100];
- fprintf(stderr, HFORMAT, "-value-", "-field description-");
- for (i=0; i<NUM_FIELDS; i++)
- {
- if ((int)(per_field[i].addr_of_field) - (int)(&stub_info) < stub_info.struct_length)
- {
- per_field[i].val2string(per_field[i].addr_of_field, buf);
- fprintf(stderr, HFORMAT, buf, per_field[i].long_name);
- }
- }
- exit(0);
- }
-
- if (argc > 2)
- {
- int f, got, got_any = 0;
- char fname[100], fval[100];
- for (i=2; i < argc; i++)
- {
- fname[0] = 0;
- fval[0] = 0;
- sscanf(argv[i], "%[^=]=%s", fname, fval);
- got = 0;
- for (f=0; f<NUM_FIELDS; f++)
- {
- if (strcmp(per_field[f].short_name, fname) == 0)
- {
- got = 1;
- got_any = 1;
- if ((int)(per_field[i].addr_of_field) - (int)(&stub_info) < stub_info.struct_length)
- {
- per_field[f].string2val(per_field[f].addr_of_field, fval);
- }
- else
- fprintf(stderr, "Warning: This stub does not support field %s\n", fname);
- }
- }
- if (!got)
- {
- fprintf(stderr, "Error: %s is not a valid field name.\n", fname);
- give_help();
- }
- }
- if (got_any)
- store_info(argv[1]);
- return 0;
- }
-
- need_to_save = 0;
- for (i=0; i<NUM_FIELDS; i++)
- {
- char buf[100], *resp;
- if ((int)(per_field[i].addr_of_field) - (int)(&stub_info) < stub_info.struct_length)
- {
- per_field[i].val2string(per_field[i].addr_of_field, buf);
- if ((resp = pose_question(per_field[i].long_name, buf)) != 0)
- {
- per_field[i].string2val(per_field[i].addr_of_field, resp);
- need_to_save = 1;
- }
- }
- }
- if (need_to_save)
- store_info(argv[1]);
-
- return 0;
- }
-