home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / stub / stubedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-26  |  6.2 KB  |  293 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7.  
  8. #ifdef __DJGPP__
  9. #include <io.h>
  10. #endif
  11.  
  12. #include "../../include/stubinfo.h"
  13.  
  14. unsigned long size_of_stubinfo = 0;
  15. char *client_stub_info;
  16.  
  17. void find_info(char *filename)
  18. {  
  19.   FILE *f;
  20.   unsigned char header[4];
  21.   unsigned char test_magic[16];
  22.  
  23.   f = fopen(filename, "rb");
  24.   if (f == 0)
  25.   {
  26.     char buf[100];
  27.     sprintf(buf, "Fatal error in stubedit reading %s", filename);
  28.     perror(buf);
  29.     exit(1);
  30.   }
  31.  
  32.   if (fseek(f, 512L, 0) != 0 ||
  33.       fread(test_magic, 1, 16, f) != 16 ||
  34.       memcmp(test_magic, "go32stub", 8) != 0)
  35.   {
  36.     printf("Error: %s is not a go32 v2.0 or higher stub\n", filename);
  37.     exit(1);
  38.   }
  39.  
  40.   fread(header, 4, 1, f);
  41.   size_of_stubinfo = (header[0]) | (header[1]<<8)
  42.                    | (header[2])<<16 | (header[3]<<24);
  43.  
  44.   fseek(f, 512L, 0);
  45.   client_stub_info = (char *)malloc(size_of_stubinfo);
  46.   fread(client_stub_info, size_of_stubinfo, 1, f);
  47.  
  48.   fclose(f);
  49.   return;
  50. }
  51.  
  52. void store_info(char *filename)
  53. {
  54.   FILE *f;
  55.   f = fopen(filename, "r+b");
  56.   if (f == 0)
  57.   {
  58.     char buf[100];
  59.     sprintf(buf, "Fatal error in stubedit writing %s", filename);
  60.     perror(buf);
  61.     exit(1);
  62.   }
  63.   fseek(f, 512L, 0);
  64.   fwrite(client_stub_info, 1, size_of_stubinfo, f);
  65.   fclose(f);
  66. }
  67.  
  68. char *pose_question(char *question, char *default_answer)
  69. {
  70.   static char response[200];
  71.   printf("%s ? [%s] ", question, default_answer);
  72.   fflush(stdout);
  73.   gets(response);
  74.   if (response[0] == '\0')
  75.     return 0;
  76.   return response;
  77. }
  78.  
  79. typedef void (*PerFunc)(void *address_of_field, char *buffer);
  80.  
  81. void str_v2s(void *addr, char *buf, int len)
  82. {
  83.   if (*(char *)addr == 0)
  84.     strcpy(buf, "\"\"");
  85.   else
  86.   {
  87.     buf[len] = 0;
  88.     strncpy(buf, (char *)addr, len);
  89.   }
  90. }
  91.  
  92. void str_s2v(void *addr, char *buf, int len)
  93. {
  94.   if (strcmp(buf, "\"\"") == 0)
  95.     *(char *)addr = 0;
  96.   else
  97.   {
  98.     ((char *)addr)[len-1] = 0;
  99.     strncpy((char *)addr, buf, len);
  100.   }
  101. }
  102.  
  103. void str_v2s8(void *addr, char *buf)
  104. {
  105.   str_v2s(addr, buf, 8);
  106. }
  107.  
  108. void str_s2v8(void *addr, char *buf)
  109. {
  110.   str_s2v(addr, buf, 8);
  111. }
  112.  
  113. void str_v2s16(void *addr, char *buf)
  114. {
  115.   str_v2s(addr, buf, 16);
  116. }
  117.  
  118. void str_s2v16(void *addr, char *buf)
  119. {
  120.   str_s2v(addr, buf, 16);
  121. }
  122.  
  123. void num_v2s(void *addr, char *buf)
  124. {
  125.   unsigned long v = *(unsigned long *)addr;
  126.   sprintf(buf, "%#lx (%dk)", v, v / 1024L);
  127. }
  128.  
  129. void num_s2v(void *addr, char *buf)
  130. {
  131.   unsigned long r = 0;
  132.   char s = 0;
  133.   sscanf(buf, "%i%c", &r, &s);
  134.   switch (s)
  135.   {
  136.     case 'k':
  137.     case 'K':
  138.       r *= 1024L;
  139.       break;
  140.     case 'm':
  141.     case 'M':
  142.       r *= 1048576L;
  143.       break;
  144.   }
  145.   *(unsigned long *)addr = r;
  146. }
  147.  
  148. struct {
  149.   char *short_name;
  150.   char *long_name;
  151.   int offset_of_field;
  152.   PerFunc val2string;
  153.   PerFunc string2val;
  154. } per_field[] = {
  155.   {
  156.     "minstack",
  157.     "Minimum amount of stack space (bytes/K/M)",
  158.     STUBINFO_MINSTACK,
  159.     num_v2s, num_s2v
  160.   },
  161.   {
  162.     "bufsize",
  163.     "Size of real-memory transfer buffer (bytes/K/M)",
  164.     STUBINFO_MINKEEP,
  165.     num_v2s, num_s2v
  166.   },
  167.   {
  168.     "runfile",
  169.     "Base name of file to actually run (max 8 chars, \"\"=self)",
  170.     STUBINFO_BASENAME,
  171.     str_v2s8, str_s2v8
  172.   },
  173.   {
  174.     "argv0",
  175.     "Value to pass as file component of argv[0] (max 16 chars, \"\"=default)",
  176.     STUBINFO_ARGV0,
  177.     str_v2s16, str_s2v16
  178.   },
  179.   {
  180.     "dpmi",
  181.     "Program to load to provide DPMI services (if needed)",
  182.     STUBINFO_DPMI_SERVER,
  183.     str_v2s16, str_s2v16
  184.   }
  185. };
  186.  
  187. #define NUM_FIELDS (sizeof(per_field) / sizeof(per_field[0]))
  188.  
  189. #define HFORMAT "%-16s %s\n"
  190.  
  191. void give_help(void)
  192. {
  193.   int i;
  194.   fprintf(stderr, "Usage: stubedit [-v] [-h] filename.exe [field=value . . . ]\n");
  195.   fprintf(stderr, "-h = give help   -v = view info  field=value means set w/o prompt\n");
  196.   fprintf(stderr, HFORMAT, "-field-", "-description-");
  197.  
  198.   for (i=0; i < NUM_FIELDS; i++)
  199.     fprintf(stderr, HFORMAT, per_field[i].short_name, per_field[i].long_name);
  200.   exit(1);
  201. }
  202.  
  203. main(int argc, char **argv)
  204. {
  205.   int view_only = 0;
  206.   int i;
  207.   int need_to_save;
  208.  
  209.   if (argc > 1 && strcmp(argv[1], "-h") == 0)
  210.     give_help();
  211.  
  212.   if (argc > 1 && strcmp(argv[1], "-v") == 0)
  213.   {
  214.     view_only = 1;
  215.     argc--;
  216.     argv++;
  217.   }
  218.  
  219.   if (argc < 2)
  220.     give_help();
  221.  
  222.   find_info(argv[1]);
  223.  
  224.   if (view_only)
  225.   {
  226.     char buf[100];
  227.     fprintf(stderr, HFORMAT, "-value-", "-field description-");
  228.     for (i=0; i<NUM_FIELDS; i++)
  229.     {
  230.       if (per_field[i].offset_of_field < size_of_stubinfo)
  231.       {
  232.         per_field[i].val2string(client_stub_info + per_field[i].offset_of_field, buf);
  233.         fprintf(stderr, HFORMAT, buf, per_field[i].long_name);
  234.       }
  235.     }
  236.     exit(0);
  237.   }
  238.  
  239.   if (argc > 2)
  240.   {
  241.     int f, got, got_any = 0;
  242.     char fname[100], fval[100];
  243.     for (i=2; i < argc; i++)
  244.     {
  245.       fname[0] = 0;
  246.       fval[0] = 0;
  247.       sscanf(argv[i], "%[^=]=%s", fname, fval);
  248.       got = 0;
  249.       for (f=0; f<NUM_FIELDS; f++)
  250.       {
  251.         if (strcmp(per_field[f].short_name, fname) == 0)
  252.         {
  253.           got = 1;
  254.           got_any = 1;
  255.           if (per_field[i].offset_of_field < size_of_stubinfo)
  256.           {
  257.             per_field[f].string2val(client_stub_info + per_field[f].offset_of_field, fval);
  258.           }
  259.           else
  260.             fprintf(stderr, "Warning: This stub does not support field %s\n", fname);
  261.         }
  262.       }
  263.       if (!got)
  264.       {
  265.         fprintf(stderr, "Error: %s is not a valid field name.\n", fname);
  266.         give_help();
  267.       }
  268.     }
  269.     if (got_any)
  270.       store_info(argv[1]);
  271.     return 0;
  272.   }
  273.  
  274.   need_to_save = 0;
  275.   for (i=0; i<NUM_FIELDS; i++)
  276.   {
  277.     char buf[100], *resp;
  278.     if (per_field[i].offset_of_field < size_of_stubinfo)
  279.     {
  280.       per_field[i].val2string(client_stub_info + per_field[i].offset_of_field, buf);
  281.       if ((resp = pose_question(per_field[i].long_name, buf)) != 0)
  282.       {
  283.         per_field[i].string2val(client_stub_info + per_field[i].offset_of_field, resp);
  284.         need_to_save = 1;
  285.       }
  286.     }
  287.   }
  288.   if (need_to_save)
  289.     store_info(argv[1]);
  290.  
  291.   return 0;
  292. }
  293.