home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1955 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  33.0 KB

  1. From: wmark@wb3ffv.ampr.org (Mark Winsor)
  2. Newsgroups: alt.sources
  3. Subject: Binary editor
  4. Message-ID: <3717@wb3ffv.ampr.org>
  5. Date: 13 Oct 90 16:06:38 GMT
  6.  
  7. Here is a binary editor that i've found useful. It has only been tested in
  8. SYSV & SCO XENIX environments, but should be relatively easy to port. Do to
  9. the non-standard alternate character set mapping prior to SYSV3, the line 
  10. drawing characters are replaced with, |, -, and + for those environments 
  11. (or if your terminal doesn't support line drawing charaters).
  12.  
  13. Mark S. Winsor
  14. Systems Analyst
  15. ProVAR, Inc.
  16.  
  17.  
  18. -------------------------------CUT HERE---------------------------------
  19. #!/bin/sh
  20. # to extract, remove the header and type "sh filename"
  21. if `test ! -s ./Makefile`
  22. then
  23. echo "writing ./Makefile"
  24. cat > ./Makefile << '\Rogue\Monster\'
  25. # The XENIX define is used for any system that uses xenix style echoing
  26.  
  27. OBJS = filepatch.o bxline.o getword.o getattrs.o
  28.  
  29. SOURCE = filepatch.c bxline.c getword.c getattrs.c
  30.  
  31. make:
  32.     @echo "You must specify system type (i.e. sys5.3 or sco, etc)"
  33.  
  34. sys5.3:
  35.     make filepatch "FLAGS = -O -g -c -D SYSV3"\
  36.                    "LDFLAGS = -g -lcurses"
  37.  
  38. ncr:
  39.     make filepatch "FLAGS = -O -c -D XENIX"\
  40.                    "LDFLAGS = -s -lcurses"
  41.  
  42. sco:
  43.     make filepatch "FLAGS = -O -c -D SCO286"\
  44.                    "LDFLAGS = -s -Ml -F 4000 -lx -lcurses"
  45.  
  46. clean:
  47.     rm -f *\.o filepatch core
  48.  
  49. filepatch: $(OBJS)
  50.         cc $(OBJS) -o filepatch $(LDFLAGS)
  51.  
  52. .c.o:
  53.         cc $(FLAGS) $*.c
  54.  
  55. \Rogue\Monster\
  56. else
  57.   echo "will not over write ./Makefile"
  58. fi
  59. if `test ! -s ./bxline.c`
  60. then
  61. echo "writing ./bxline.c"
  62. cat > ./bxline.c << '\Rogue\Monster\'
  63. /* 
  64.  *  This is a routine to place a solid line border 
  65.  *  around a window.    Mark S. Winsor
  66.  *                      ProVAR 
  67.  */ 
  68.  
  69. static char rcsid[] = "$Id: bxline.c,v 1.2 90/10/10 21:03:48 wmark Exp $";
  70. static char rcsrev[] = "$Revision: 1.2 $";
  71.  
  72. /*
  73. $Author: wmark $
  74. $Date: 90/10/10 21:03:48 $
  75. $Locker:  $
  76. $RCSfile: bxline.c,v $
  77. $Source: /usr9/people/mark/C/filepatch/bxline.c,v $
  78. $State: Exp $
  79.  
  80. $Log:    bxline.c,v $
  81.  * Revision 1.2  90/10/10  21:03:48  wmark
  82.  * Took out color
  83.  * 
  84.  * Revision 1.1  90/07/29  18:00:24  wmark
  85.  * Initial revision
  86.  * 
  87. */
  88.  
  89. #include <curses.h>
  90.  
  91. #ifdef SCO286
  92. #define XENIX
  93. #endif
  94.  
  95. bxline(towindow, vert_len, horz_len )
  96.  
  97. char *towindow;
  98. int vert_len;
  99. int horz_len;
  100.  
  101. {
  102.         int a;
  103.         int b;
  104.         int line;
  105.         extern int altchar;
  106.         char *acsc_ptr;
  107.         char acsc_arr[80];
  108.         char upperright;
  109.         char upperleft;
  110.         char lowerright;
  111.         char lowerleft;
  112.         char horizontal;
  113.         char vertical;
  114.  
  115. #ifdef SYSV3
  116.         upperright = ACS_URCORNER;
  117.         upperleft  = ACS_ULCORNER;
  118.         lowerright = ACS_LRCORNER;
  119.         lowerleft  = ACS_LLCORNER;
  120.         horizontal = ACS_HLINE;
  121.         vertical   = ACS_VLINE;
  122. #else
  123.         upperright = '+';
  124.         upperleft  = '+';
  125.         lowerright = '+';
  126.         lowerleft  = '+';
  127.         horizontal = '-';
  128.         vertical   = '|';
  129. #endif
  130.         
  131. #ifdef SYSV3
  132.         (void) wattrset(towindow,A_ALTCHARSET);
  133. #endif
  134.         (void) mvwprintw(towindow,0,0,"%c",upperleft);
  135.         (void) mvwprintw(towindow,0,(horz_len - 1),"%c",upperright);
  136.         (void) mvwprintw(towindow,(vert_len - 1),0,"%c",lowerleft);
  137.         (void) mvwprintw(towindow,(vert_len - 1),(horz_len - 1),"%c",
  138.                 lowerright);
  139.         a = 0;
  140.         b = horz_len - 1;
  141.         line = 1;
  142.         while ( line < (vert_len - 1)) {
  143.              (void) mvwprintw (towindow,line,a,"%c",vertical);
  144.              (void) mvwprintw (towindow,line,b,"%c",vertical);
  145.              ++line;
  146.         }
  147.         a = 0;
  148.         for ( b = 1; b < (horz_len - 1); ++b) {
  149.              (void) mvwprintw (towindow,a,b,"%c",horizontal);
  150.         }
  151.         a = vert_len - 1;
  152.         for ( b = 1; b < (horz_len - 1); ++b) {
  153.              (void) mvwprintw (towindow,a,b,"%c",horizontal);
  154.         }
  155.         (void) wrefresh(towindow);
  156.         (void) wattrset(towindow,0);
  157. }
  158. \Rogue\Monster\
  159. else
  160.   echo "will not over write ./bxline.c"
  161. fi
  162. if `test ! -s ./filepatch.c`
  163. then
  164. echo "writing ./filepatch.c"
  165. cat > ./filepatch.c << '\Rogue\Monster\'
  166. /*
  167.  *      Norton-esque file patch utility program
  168.  *
  169.  *      Copyright ProVAR, Inc. &
  170.  *                Emtronix Data Services
  171.  *
  172.  *      Mark S. Winsor
  173.  *      Marc A. Siegel
  174.  *
  175.  *      This program may be freely distributed provided this notice remains
  176.  *
  177.  *      Send any bug reports, questions, or suggestions to 
  178.  *      {uunet}!cp1!briar!mas!bohica!wmark
  179.  */
  180.  
  181. static char rcsid[] = "$Id: filepatch.c,v 1.12 90/10/10 21:03:24 wmark Exp $";
  182. static char rcsrev[] = "$Revision: 1.12 $";
  183.  
  184. /*
  185. $Author: wmark $
  186. $Date: 90/10/10 21:03:24 $
  187. $Locker:  $
  188. $RCSfile: filepatch.c,v $
  189. $Source: /usr9/people/mark/C/filepatch/filepatch.c,v $
  190. $State: Exp $
  191.  
  192. $Log:    filepatch.c,v $
  193.  * Revision 1.12  90/10/10  21:03:24  wmark
  194.  * fixed display
  195.  * 
  196.  * Revision 1.11  90/08/13  12:53:42  wmark
  197.  * Repeat last search if no argument given
  198.  * 
  199.  * Revision 1.9  90/08/13  10:15:28  wmark
  200.  * Added relative offsets (using "+" or "-" in first character of offset)
  201.  * 
  202.  * Revision 1.3  90/07/30  09:26:07  wmark
  203.  * Centered title line
  204.  * 
  205.  * Revision 1.2  90/07/29  18:19:44  wmark
  206.  * Use RCS revision number in title line
  207.  * 
  208.  * Revision 1.1  90/07/29  18:17:58  wmark
  209.  * Initial revision
  210.  * 
  211. */
  212.  
  213.  
  214. #include <curses.h>
  215. #include <ctype.h>
  216. #include <fcntl.h>
  217. #include <signal.h>
  218. #include <errno.h>
  219.  
  220. #define ESC    '\033'
  221. #define TAB    '\011'
  222. #define NUMBUF 25
  223. #define MAX    256
  224. #define MAXPAT 40
  225. #define MAXHEX 20
  226.  
  227. #ifdef SCO286
  228. #define XENIX
  229. #endif
  230.  
  231. int colors;
  232. int blink;
  233. int reverse;
  234. int altchar;
  235. int underline;
  236. int edit_type;    /* 0 = edit hex, 1 = edit chars */
  237. char lastsearch[MAXPAT];
  238.  
  239. struct scr_pos {
  240.     int h_scr_row;
  241.     int h_scr_col;
  242.     int c_scr_row;
  243.     int c_scr_col;
  244. };
  245.  
  246. /*  
  247.  * This table below is used instead of printw("%X") for two reasons.
  248.  * 1 - speed, and 2 - there appears to be a problem with printf type
  249.  * commands printing hex FF on Xenix and ncr systems.
  250.  */
  251.  
  252. char *hexconv[] = { "00", "01", "02", "03", "04", "05", "06", "07", "08",
  253.                     "09", "0A", "0B", "0C", "0D", "0E", "0F",
  254.                     "10", "11", "12", "13", "14", "15", "16", "17", "18",
  255.                     "19", "1A", "1B", "1C", "1D", "1E", "1F",
  256.                     "20", "21", "22", "23", "24", "25", "26", "27", "28",
  257.                     "29", "2A", "2B", "2C", "2D", "2E", "2F",
  258.                     "30", "31", "32", "33", "34", "35", "36", "37", "38",
  259.                     "39", "3A", "3B", "3C", "3D", "3E", "3F",
  260.                     "40", "41", "42", "43", "44", "45", "46", "47", "48",
  261.                     "49", "4A", "4B", "4C", "4D", "4E", "4F",
  262.                     "50", "51", "52", "53", "54", "55", "56", "57", "58",
  263.                     "59", "5A", "5B", "5C", "5D", "5E", "5F",
  264.                     "60", "61", "62", "63", "64", "65", "66", "67", "68",
  265.                     "69", "6A", "6B", "6C", "6D", "6E", "6F",
  266.                     "70", "71", "72", "73", "74", "75", "76", "77", "78",
  267.                     "79", "7A", "7B", "7C", "7D", "7E", "7F",
  268.                     "80", "81", "82", "83", "84", "85", "86", "87", "88",
  269.                     "89", "8A", "8B", "8C", "8D", "8E", "8F",
  270.                     "90", "91", "92", "93", "94", "95", "96", "97", "98",
  271.                     "99", "9A", "9B", "9C", "9D", "9E", "9F",
  272.                     "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8",
  273.                     "A9", "AA", "AB", "AC", "AD", "AE", "AF",
  274.                     "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8",
  275.                     "B9", "BA", "BB", "BC", "BD", "BE", "BF",
  276.                     "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8",
  277.                     "C9", "CA", "CB", "CC", "CD", "CE", "CF",
  278.                     "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8",
  279.                     "D9", "DA", "DB", "DC", "DD", "DE", "DF",
  280.                     "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8",
  281.                     "E9", "EA", "EB", "EC", "ED", "EE", "EF",
  282.                     "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
  283.                     "F9", "FA", "FB", "FC", "FD", "FE", "FF" 
  284.                  };
  285.  
  286. main(argc,argv)
  287. int argc;
  288. char *argv[];
  289. {
  290.     int input;
  291.  
  292.     if (argc != 2) {
  293.         (void) usage(argv[0]);
  294.     }
  295.     if ((input = open(argv[1],O_RDWR)) == -1) {
  296.         (void) fprintf(stderr,"%s: Cannot open %s, error %d\n",
  297.                  argv[0],argv[1],errno);
  298.         (void) exit(1);
  299.     }
  300.     edit_type = 0;
  301.     lastsearch[0] = '\0';
  302.     (void) process_file (input,argv[1]);
  303.     (void) close(input);
  304.     (void) exit(0);
  305. }
  306.  
  307. process_file(input,filename)
  308. int input;
  309. char *filename;
  310. {
  311.     static char buffer[MAX];
  312.     long seek_no;
  313.     int max;
  314.     int proc_ret;
  315.     int byebye();
  316.     long end_of_file;
  317.     long lseek();
  318.  
  319.     (void) initscr();
  320.     (void) raw();
  321. #ifndef XENIX
  322.     (void) noecho();
  323. #endif
  324.     (void) keypad(stdscr,TRUE);
  325.     (void) signal(SIGINT,byebye);
  326.     (void) signal(SIGQUIT,byebye);
  327.     (void) get_attrs();
  328.     (void) bxline(stdscr,23,80);
  329.     if (reverse == TRUE) {
  330.         (void) attrset(A_REVERSE);
  331.     }
  332.     (void) mvprintw(0,20," ProVAR File Patch Utility   ");
  333.     (void) printw("Rev: %c%c%c%c ",rcsrev[11],rcsrev[12],rcsrev[13],rcsrev[14]);
  334.     (void) attrset(0);
  335.     (void) mvprintw(2,3,"File Name: %-40.40s",filename);
  336.     (void) mvprintw(21,28,"Enter '?' for help");
  337.  
  338.     seek_no = 0;
  339.     end_of_file = lseek(input,0L,2);
  340.     for (;;) {
  341.         (void) mvprintw(2,55,"Offset: %7ld bytes",seek_no);
  342.         (void) move(23,0);
  343.         (void) clrtoeol();
  344.         if (lseek(input,seek_no,0) == -1)
  345.             break;
  346.         max = read(input,buffer,MAX);
  347.         if (max < 1) 
  348.             break;
  349.         proc_ret = process_buf(buffer,max,&seek_no,end_of_file,input);
  350.         if (proc_ret == -1)
  351.             break;
  352.         if (proc_ret == 1) {
  353.             if (lseek(input,seek_no,0) == -1)
  354.                 break;
  355.             (void) write(input,buffer,max);
  356.         }
  357.     }
  358.     (void) erase();
  359.     (void) mvprintw(12,25,"-- Finished Processing --");
  360.     (void) refresh();
  361.     (void) endwin();
  362. }
  363.  
  364. process_buf(buffer,max,seek_ptr,end_of_file,input)
  365. char *buffer;
  366. int max;
  367. long *seek_ptr;
  368. long end_of_file;
  369. int input;
  370. {
  371.     int index;
  372.  
  373.     for (index = 0; index < max; index++) {
  374.         (void) disp_char(*(buffer + index),index);
  375.     }
  376.     for ( ; index < MAX; index++) {
  377.         (void) erase_char(index);
  378.     }
  379.     return(update_buf(buffer,max,seek_ptr,end_of_file,input));
  380. }
  381.  
  382. update_buf(buffer,max,seek_ptr,end_of_file,input)
  383. char *buffer;
  384. int max;
  385. long *seek_ptr;
  386. long end_of_file;
  387. int input;
  388. {
  389.     struct scr_pos pos;
  390.     unsigned int i;
  391.     int index;
  392.     int oldindex;
  393.     long new_offset;
  394.     long get_new_offset();
  395.     long get_pattern();
  396.     long lseek();
  397.     int c;
  398.     char chgs_made;
  399.     char answer;
  400.     char mode;
  401.     char hex_string[3];
  402.  
  403.     mode = 'C';                    /* C = Command, E = Edit */
  404.     index = 0;
  405.     chgs_made = 'N';
  406.  
  407.     for (;;) {
  408.         if (mode == 'C') {
  409.             (void) mvprintw(23,0,"Command Mode");
  410.             (void) refresh();
  411.         }
  412.         else {
  413.             (void) mvprintw(23,0,"Edit mode   ");
  414.             (void) refresh();
  415.         }
  416.         (void) pos_char(index,&pos);
  417.         if (edit_type == 0) {
  418.             (void) move (pos.h_scr_row,pos.h_scr_col);
  419.         }
  420.         else {
  421.             (void) move (pos.c_scr_row,pos.c_scr_col);
  422.         }
  423.         (void) refresh();
  424.         c = getch();
  425.  
  426.         if (mode == 'E') {
  427.             switch(c) {
  428.  
  429.                 case ESC:
  430.                 case TAB:
  431.                          mode = 'C';
  432.                          break;
  433.  
  434.                 default:
  435.                          if (edit_type == 0) {
  436.                              c = toupper(c);
  437.                              hex_string[0] = c;
  438.                              (void) move (pos.h_scr_row,(pos.h_scr_col + 1));
  439.                              (void) refresh();
  440.                              c = getch();
  441.                              c = toupper(c);
  442.                              hex_string[1] = c;
  443.                              hex_string[2] = '\0';
  444.                              if (hex_string[0] < '0' || hex_string[0] > '9') {
  445.                                  if (hex_string[0] < 'A' 
  446.                                  || hex_string[0] > 'F') {
  447.                                      (void) beep();
  448.                                      break;
  449.                                  }
  450.                              }
  451.                              if (hex_string[1] < '0' || hex_string[1] > '9') {
  452.                                  if (hex_string[1] < 'A' 
  453.                                  || hex_string[1] > 'F') {
  454.                                      (void) beep();
  455.                                      break;
  456.                                  }
  457.                              }
  458.                              (void) sscanf(hex_string,"%x",&i);
  459.                          }
  460.                          else {
  461.                              i = c;
  462.                          }
  463.                          *(buffer + index) = i;
  464.                          (void) disp_char(*(buffer + index),index);
  465.                          chgs_made = 'Y';
  466.                          ++index;
  467.                          if (index >= max)
  468.                              index = 0;
  469.                          break;
  470.             }
  471.         }
  472.         else {
  473.             switch(c) {
  474.  
  475.                 case ESC:
  476.                 case TAB:
  477.                          mode = 'E';
  478.                          break;
  479.  
  480.                 case 'W':
  481.                 case 'w':
  482.                          (void) mvprintw(23,0,"... Writing     ");
  483.                          (void) refresh();
  484.                          return(1);
  485.  
  486.                 case 'E':
  487.                 case 'e':
  488.                          *seek_ptr = end_of_file - 256;
  489.                          if (*seek_ptr < 0) {
  490.                              *seek_ptr = 0;
  491.                          }
  492.                          return(0);
  493.  
  494.                 case 'Q':
  495.                 case 'q':
  496.                          if (chgs_made == 'Y') {
  497.                              answer = ask_ignore();
  498.                          }
  499.                          if (chgs_made == 'Y' && answer == 'N') {
  500.                              break;
  501.                          }
  502.                          else {
  503.                              return(-1);
  504.                          }
  505.  
  506.                 case '?':
  507.                          (void) help();
  508.                          break;
  509.  
  510.                 case 'T':
  511.                 case 't':
  512.                          edit_type ^= 1;
  513.                          break;
  514.  
  515.                 case 'O':
  516.                 case 'o':
  517.                          new_offset = get_new_offset(*seek_ptr);
  518.                          if (new_offset < 0 || new_offset > end_of_file) {
  519.                              (void) error("Offset out of range");
  520.                              break;
  521.                          }
  522.                          else {
  523.                              *seek_ptr = new_offset;
  524.                              return(0);
  525.                          }
  526.  
  527.                 case '/':
  528.                          if (chgs_made == 'Y') {
  529.                              answer = ask_ignore();
  530.                          }
  531.                          if (chgs_made == 'Y' && answer == 'N') {
  532.                              break;
  533.                          }
  534.                          else {
  535.                              new_offset = get_pattern((*seek_ptr + index),
  536.                                                      buffer,max,input);
  537.                              (void) move(23,0);
  538.                              (void) clrtoeol();
  539.                              (void) refresh();
  540.                              if (new_offset == -1) {             /* Not found */
  541.                                  (void) error("Pattern not found");
  542.                                  break;
  543.                              }
  544.                              if (new_offset == -2) {                /*Not fnd */
  545.                                  (void) error("Pattern not found"); /*re-read */
  546.                                  lseek(input,*seek_ptr,0);          /*required*/
  547.                                  max = read(input,buffer,MAX);
  548.                                  break;
  549.                              }
  550.                              if (new_offset == -3) {
  551.                                  break;
  552.                              }
  553.                              else {
  554.                                  *seek_ptr = new_offset;
  555.                                  return(0);
  556.                              }
  557.                          }
  558.  
  559.                 case KEY_RIGHT:
  560.                 case 'R':
  561.                 case 'r':
  562.                          ++index;
  563.                          if (index > max) {
  564.                              --index;
  565.                              (void) beep();
  566.                          }
  567.                          break;
  568.  
  569.                 case KEY_LEFT:
  570.                 case 'L':
  571.                 case 'l':
  572.                          --index;
  573.                          if (index < 0) {
  574.                              index = 0;
  575.                              (void) beep();
  576.                          }
  577.                          break;
  578.  
  579.                 case KEY_DOWN:
  580.                 case 'D':
  581.                 case 'd':
  582.                          index += 16;
  583.                          if (index >= max) {
  584.                              index -= 16;
  585.                              (void) beep();
  586.                          }
  587.                          break;
  588.  
  589.                 case KEY_UP:
  590.                 case 'U':
  591.                 case 'u':
  592.                          index -= 16;
  593.                          if (index < 0) {
  594.                              index += 16;
  595.                              (void) beep();
  596.                          }
  597.                          break;
  598.  
  599.                 case '\n':
  600.                          oldindex = index;
  601.                          index += 16;
  602.                          index = index - (index % 16);
  603.                          if (index >= max) {
  604.                              index = oldindex;
  605.                              (void) beep();
  606.                          }
  607.                          break;
  608.  
  609.                 case 'F':
  610.                 case 'f':
  611.                          if (chgs_made == 'Y') {
  612.                              answer = ask_ignore();
  613.                          }
  614.                          if (chgs_made == 'Y' && answer == 'N') {
  615.                              break;
  616.                          }
  617.                          else {
  618.                              *seek_ptr += MAX;
  619.                              if (*seek_ptr >= end_of_file) {
  620.                                  (void) error("No pages after this one");
  621.                                  *seek_ptr -= MAX;
  622.                                  break;
  623.                              }
  624.                              else {
  625.                                  return(0);
  626.                              }
  627.                          }
  628.  
  629.                 case 'B':
  630.                 case 'b':
  631.                          if (chgs_made == 'Y') {
  632.                              answer = ask_ignore();
  633.                          }
  634.                          if (chgs_made == 'Y' && answer == 'N') {
  635.                              break;
  636.                          }
  637.                          else {
  638.                              if (*seek_ptr == 0) {
  639.                                  (void) error("No pages before this one");
  640.                                  break;
  641.                              }
  642.                              else {
  643.                                  *seek_ptr -= MAX;
  644.                                  if (*seek_ptr < 0) 
  645.                                      *seek_ptr = 0;
  646.                                  return(0);
  647.                              }
  648.                          }
  649.  
  650.                 default:
  651.                          (void) beep();
  652.                          break;
  653.             }         
  654.         }         
  655.     }
  656. }
  657.  
  658. ask_ignore()
  659. {
  660.     int answer;
  661.     
  662.     (void) mvprintw(23,0, "This will ignore changes in this block, ");
  663.     (void) printw("Is this ok ? ");
  664.     do {
  665.         (void) move(23,53);
  666.         (void) refresh();
  667.         answer = getch();
  668.         answer = toupper(answer);
  669.         (void) move(23,53);
  670.         (void) addch(answer);
  671.         (void) refresh();
  672.     } while(answer != 'N' && answer != 'Y');
  673.     (void) move(23,0);
  674.     (void) clrtoeol();
  675.     return(answer);
  676. }
  677.  
  678. long
  679. get_new_offset(oldoffset)
  680. long oldoffset;
  681. {
  682.     long offset;
  683.     char offsetbuf[15];
  684.  
  685. #ifndef XENIX
  686.     (void) echo();
  687. #endif
  688.     (void) mvprintw(23,0,"Enter Offset: ");
  689.     offsetbuf[0] = '\0';
  690.     (void) get_word(14,offsetbuf,stdscr,23,14);
  691.     if (offsetbuf[0] == '\0') {
  692.         offset = -1;
  693.     }
  694.     else if (offsetbuf[0] == '+' || offsetbuf[0] == '-') {
  695.         if ((sscanf(offsetbuf,"%ld",&offset)) != 1) {
  696.             offset = -1;
  697.         }
  698.         else {
  699.             offset += oldoffset;
  700.         }
  701.     }
  702.     else {
  703.         if ((sscanf(offsetbuf,"%ld",&offset)) != 1) {
  704.             offset = -1;
  705.         }
  706.     }
  707.     (void) move(23,0);
  708.     (void) clrtoeol();
  709. #ifndef XENIX
  710.     (void) noecho();
  711. #endif
  712.     return(offset);
  713. }
  714.  
  715. long
  716. get_pattern(offset,buffer,max,input)
  717. long offset;
  718. char *buffer;
  719. int max;
  720. int input;
  721. {
  722.     static char pat[MAXPAT];
  723.     int         wordresult;
  724.     long        search();
  725.  
  726. #ifndef XENIX
  727.     (void) echo();
  728. #endif
  729.     (void) mvprintw(23,0,"Enter pattern (ESC to enter in hex): ");
  730.     pat[0] = '\0';
  731.     wordresult = get_word(MAXPAT,pat,stdscr,23,37);
  732.     if (wordresult == 6) {          /* The get_word() func is overkill     */
  733.         (void) hex_pattern(pat);    /* but I use it often in other         */
  734.     }                               /* things, so why re-invent the wheel! */
  735.  
  736.     if (pat[0] == '\0') {
  737. #ifndef XENIX
  738.         (void) noecho();
  739. #endif
  740.         if (lastsearch[0] == '\0') {
  741.             return(-3);
  742.         }
  743.         else {
  744.             (void) strcpy(pat,lastsearch);
  745.         }
  746.     }
  747.     (void) move(23,0);
  748.     (void) clrtoeol();
  749.     (void) mvprintw(23,0,"... Searching");
  750.     (void) refresh();
  751. #ifndef XENIX
  752.     (void) noecho();
  753. #endif
  754.     (void) strcpy(lastsearch,pat);
  755.     return(search(pat,buffer,offset,max,input));
  756. }
  757.  
  758. hex_pattern(pat)
  759. char *pat;
  760. {
  761.     int i;
  762.     int j;
  763.     int c;
  764.     char hex_string[3];
  765.  
  766. #ifndef XENIX
  767.     (void) noecho();
  768. #endif
  769.     (void) move(23,0);
  770.     (void) clrtoeol();
  771.     (void) mvprintw(23,0,"Enter hex characters:");
  772.     (void) refresh();
  773.     i = 0;
  774.     do {
  775.         (void) move(23,(22 + (i * 3)));
  776.         (void) refresh();
  777.         c = getch();
  778.         if (c != '\n') {
  779.             hex_string[0] = c;
  780.             hex_string[1] = getch();
  781.             hex_string[2] = '\0';
  782.              if (sscanf(hex_string,"%x",&c) != 1) {
  783.                  (void) beep();
  784.              }
  785.              else {
  786.                  *(pat + i) = c;
  787.                  (void) mvaddstr(23,(22 + (i * 3)),
  788.                      hexconv[(unsigned int)*(pat + i)]);
  789.                  (void) refresh();
  790.                  c = '\0';
  791.                  ++i;
  792.              }
  793.          }
  794.      } while (c != '\n' && i < MAXHEX);
  795.      ++i;
  796.      *(pat + i) = '\0';
  797. #ifndef XENIX
  798.     (void) echo();
  799. #endif
  800. }
  801.  
  802. long
  803. search(pat,buffer,offset,max,input)
  804. char *pat;
  805. char *buffer;
  806. long offset;
  807. int max;
  808. int input;
  809. {
  810.     register int index;
  811.     int pat_length;
  812.     char re_read;
  813.     static char srch_buf[MAX * NUMBUF];
  814.     char *search_buf;
  815.     long lseek();
  816.  
  817.     re_read = 'N';
  818.     pat_length = strlen(pat);
  819.     (void) memcpy(srch_buf,buffer,max);
  820.     search_buf = srch_buf;
  821.     for (;;) {
  822.         for (index = 1; index < (max - pat_length + 1); index++) {
  823.             if (*(search_buf + index) == *pat) {
  824.                 if (!memcmp((search_buf + index),pat,pat_length)) {
  825.                     return(index + offset);
  826.                 }
  827.             }
  828.         }
  829.         if (max < MAX) {
  830.             if (re_read == 'N') {
  831.                 return(-1);
  832.             }
  833.             else {
  834.                 return(-2);
  835.             }
  836.         }
  837.         offset += max;
  838.         if (lseek(input,offset,0) == -1) {
  839.             if (re_read == 'N') {
  840.                 return(-1);
  841.             }
  842.             else {
  843.                 return(-2);
  844.             }
  845.         }
  846.         max = read(input,srch_buf,(MAX * NUMBUF));
  847.         re_read = 'Y';
  848.     }
  849. }
  850.  
  851. disp_char(c,index)
  852. unsigned char c;
  853. int index;
  854. {
  855.     struct scr_pos pos;
  856.  
  857.     (void) pos_char(index,&pos);
  858.     (void) mvaddstr(pos.h_scr_row,pos.h_scr_col,hexconv[(unsigned int)c]);
  859.     if (c < ' ' || c > '~') {
  860.         c = '.';
  861.     }
  862.     (void) mvaddch(pos.c_scr_row,pos.c_scr_col,c);
  863. }
  864.  
  865. erase_char(index)
  866. int index;
  867. {
  868.     struct scr_pos pos;
  869.  
  870.     (void) pos_char(index,&pos);
  871.     (void) mvprintw(pos.h_scr_row,pos.h_scr_col,"  ");
  872.     (void) mvprintw(pos.c_scr_row,pos.c_scr_col," ");
  873. }
  874.  
  875. pos_char(index,posptr)
  876. int index;
  877. struct scr_pos *posptr;
  878. {
  879.     int st_row;
  880.     int st_col;
  881.     int calc_row;
  882.     int calc_rem;
  883.     int even_odd;
  884.  
  885.     st_row = 4;
  886.     st_col = 2;
  887.  
  888.     calc_row = index / 16;
  889.     calc_rem = index % 16;
  890.     even_odd = calc_rem % 2;
  891.     even_odd ^= 1;             /* If 0 make it one, and vice versa */
  892.  
  893.     posptr->h_scr_row = posptr->c_scr_row = st_row + calc_row;
  894.     posptr->h_scr_col = (st_col + (calc_rem * 3) + (even_odd * 1));
  895.     posptr->c_scr_col = st_col + 52 + calc_rem;
  896.     return(0);
  897. }
  898.  
  899. help()
  900. {
  901.     WINDOW *helpwin;
  902.  
  903.     helpwin = newwin(20,48,1,15);
  904.     bxline(helpwin,20,48);
  905.  
  906.     (void) mvwprintw(helpwin,1,15,"Action Key List");
  907.     (void) mvwprintw(helpwin,3,3,"ESC or TAB toggles edit/command mode");
  908.     (void) mvwprintw(helpwin,4,3,"R or Right arrow = Move to right");
  909.     (void) mvwprintw(helpwin,5,3,"L or Left arrow  = Move to left");
  910.     (void) mvwprintw(helpwin,6,3,"D or Down arrow  = Down one line");
  911.     (void) mvwprintw(helpwin,7,3,"U or Up arrow    = Up one line");
  912.     (void) mvwprintw(helpwin,8,3,"<RETURN>         = Beginning of next line");
  913.     (void) mvwprintw(helpwin,9,3,"W                = Write current buffer");
  914.     (void) mvwprintw(helpwin,10,3,"Q                = Quit processing");
  915.     (void) mvwprintw(helpwin,11,3,"F                = Forward page");
  916.     (void) mvwprintw(helpwin,12,3,"B                = Backward page");
  917.     (void) mvwprintw(helpwin,13,3,"O                = Change offset");
  918.     (void) mvwprintw(helpwin,14,3,"E                = Go to last page");
  919.     (void) mvwprintw(helpwin,15,3,"T                = Toggle hex/char edit");
  920.     (void) mvwprintw(helpwin,16,3,"/                = Pattern match");
  921.     (void) mvwprintw(helpwin,18,3,"Press Any key to continue ");
  922.     (void) wrefresh(helpwin);
  923.     (void) wgetch(helpwin);
  924.  
  925.     (void) delwin(helpwin);
  926.     (void) touchwin(stdscr);
  927. }
  928.  
  929. error(str)
  930. char *str;
  931. {
  932.     (void) mvprintw(23,0,"%s ",str);
  933.     (void) refresh();
  934.     (void) beep();
  935.     (void) getch();
  936.     (void) move(23,0);
  937.     (void) clrtoeol();
  938. }
  939.  
  940. usage(progname)
  941. char *progname;
  942. {
  943.     (void) fprintf(stderr,"Usage: %s filename\n",progname);
  944.     (void) exit(1);
  945. }
  946.  
  947. byebye()
  948. {
  949.     (void) endwin();
  950.     (void) exit(2);
  951. }
  952. \Rogue\Monster\
  953. else
  954.   echo "will not over write ./filepatch.c"
  955. fi
  956. if `test ! -s ./getattrs.c`
  957. then
  958. echo "writing ./getattrs.c"
  959. cat > ./getattrs.c << '\Rogue\Monster\'
  960.  
  961. static char rcsid[] = "$Id: getattrs.c,v 1.1 90/07/29 18:00:32 wmark Exp $";
  962. static char rcsrev[] = "$Revision: 1.1 $";
  963.  
  964. /*
  965. $Author: wmark $
  966. $Date: 90/07/29 18:00:32 $
  967. $Locker:  $
  968. $RCSfile: getattrs.c,v $
  969. $Source: /usr9/people/mark/C/filepatch/getattrs.c,v $
  970. $State: Exp $
  971.  
  972. $Log:    getattrs.c,v $
  973.  * Revision 1.1  90/07/29  18:00:32  wmark
  974.  * Initial revision
  975.  * 
  976. */
  977.  
  978. #include <curses.h>
  979.  
  980. #ifdef SCO286
  981. #define XENIX
  982. #endif
  983.  
  984. get_attrs()
  985. {
  986.     extern int blink;
  987.     extern int colors;
  988.     extern int reverse;
  989.     extern int altchar;
  990.     extern int underline;
  991.     char sm[30];
  992.  
  993.     blink = FALSE;
  994.     colors = FALSE;
  995.     reverse = FALSE;
  996.     altchar = FALSE;
  997.     underline = FALSE;
  998.  
  999. #ifdef XENIX
  1000.     if (((char *) tgetstr("bm",sm)) != NULL) { 
  1001.         blink = TRUE;
  1002.     }
  1003.     if (((char *) tgetstr("so",sm)) != NULL) { 
  1004.         reverse = TRUE;
  1005.     }
  1006.     if (((char *) tgetstr("as",sm)) != NULL) { 
  1007.         altchar = TRUE;
  1008.     }
  1009.     if (((char *) tgetstr("us",sm)) != NULL) { 
  1010.         underline = TRUE;
  1011.     }
  1012. #else
  1013.     if (((char *) tigetstr("blink")) != NULL) {
  1014.         blink = TRUE;
  1015.     }
  1016.     if (((char *) tigetstr("smso")) != NULL) {
  1017.         reverse = TRUE;
  1018.     }
  1019.     altchar = TRUE;
  1020.     if (((char *) tigetstr("smul")) != NULL) {
  1021.         underline = TRUE;
  1022.     }
  1023. #endif
  1024.  
  1025. #ifdef USECOLORS
  1026.     colors = start_color();
  1027.     if (colors != ERR) {
  1028.         colors = TRUE;
  1029.     }
  1030. #endif
  1031. }
  1032. \Rogue\Monster\
  1033. else
  1034.   echo "will not over write ./getattrs.c"
  1035. fi
  1036. if `test ! -s ./getword.c`
  1037. then
  1038. echo "writing ./getword.c"
  1039. cat > ./getword.c << '\Rogue\Monster\'
  1040. /* This is a common accept routine for all character and character
  1041.    string input.    Mark S. Winsor
  1042.                     ProVAR                                         */
  1043.  
  1044. static char rcsid[] = "$Id: getword.c,v 1.1 90/07/29 18:00:37 wmark Exp $";
  1045. static char rcsrev[] = "$Revision: 1.1 $";
  1046.  
  1047. /*
  1048. $Author: wmark $
  1049. $Date: 90/07/29 18:00:37 $
  1050. $Locker:  $
  1051. $RCSfile: getword.c,v $
  1052. $Source: /usr9/people/mark/C/filepatch/getword.c,v $
  1053. $State: Exp $
  1054.  
  1055. $Log:    getword.c,v $
  1056.  * Revision 1.1  90/07/29  18:00:37  wmark
  1057.  * Initial revision
  1058.  * 
  1059. */
  1060.  
  1061. #include <curses.h>
  1062.  
  1063. #define CTRLA '\001'
  1064. #define CTRLB '\002'
  1065. #define CTRLC '\003'
  1066. #define CTRLD '\004'
  1067. #define CTRLT '\024'
  1068. #define BELL '\007'
  1069. #define REPAINT '\014'
  1070.  
  1071. #ifndef ESC
  1072. #define ESC '\033'
  1073. #endif
  1074.  
  1075. #ifdef SCO286
  1076. #define XENIX
  1077. #endif
  1078.    
  1079. get_word(size,fld_ptr,fromwindow,beg_row,beg_col)
  1080.  
  1081. int size;
  1082. char *fld_ptr;
  1083. char *fromwindow;
  1084. int beg_row;
  1085. int beg_col;
  1086.  
  1087. {
  1088.     int offset;
  1089.     int ch;
  1090.     char fill_flag = 'y';
  1091.  
  1092.                         /* 
  1093.                          * Keypad must be enabled to use this function, 
  1094.                          * the arrow keys will return : 
  1095.                          *          1 for KEY_UP, KEY_F2,
  1096.                          *          2 for KEY_LEFT, KEY_F3,
  1097.                          *          3 for KEY_DOWN, KEY_F1,
  1098.                          *          4 for KEY_RIGHT, KEY_F4, 
  1099.                          *          and 0 for no arrow 
  1100.                          */
  1101.  
  1102. #ifndef XENIX
  1103.     (void) noecho();
  1104. #endif
  1105.     (void) wmove(fromwindow,beg_row,beg_col);
  1106.     (void) wrefresh(fromwindow);
  1107.     for (;;) {
  1108.         for (offset = 0; offset < size; offset++) {
  1109.             ch = wgetch(fromwindow);
  1110.             if (ch == REPAINT && offset == 0) {               /* If CTRL-L is */
  1111.                 (void) wmove (fromwindow,beg_row,beg_col);    /* is pressed   */
  1112.                 (void) wprintw(fromwindow,"  ");              /* in the 1'st  */
  1113.                 (void) wmove (fromwindow,beg_row,beg_col);    /* postition,   */
  1114.                 (void) clearok(fromwindow);                   /* then repaint */
  1115.                 (void) wrefresh(fromwindow);                  /* screen and   */
  1116.                 --offset;                                     /* continue     */
  1117.                 continue;
  1118.             }
  1119.             if (offset == 0) {
  1120.                 if (ch == ESC) {
  1121.                     return(6);
  1122.                 }
  1123.                 if (ch == KEY_UP || ch == CTRLB) {
  1124.                     return(1);
  1125.                 }
  1126.                 if (ch == KEY_RIGHT || ch == CTRLD) {
  1127.                     return(4);
  1128.                 }
  1129.                 if (ch == KEY_DOWN || ch == CTRLA) {
  1130.                     return(3);
  1131.                 }
  1132.                 if (ch == KEY_LEFT || ch == CTRLC) {
  1133.                     return(2);
  1134.                 }
  1135.                 if (ch == CTRLT) {
  1136.                     return(6);
  1137.                 }
  1138.             }
  1139.             if (ch == '\n' && offset == 0) {
  1140.                 return(0);
  1141.             }
  1142.             if (ch == '\n') {
  1143.                 *(fld_ptr + offset) = '\0';
  1144.                 fill_flag = 'n';
  1145.                 return(0);
  1146.             }
  1147.             if (ch == '\b') {
  1148.                 offset = offset - 2;
  1149.                 if (offset < -1) {
  1150.                     (void) putchar(BELL);
  1151.                     (void) mvwprintw(fromwindow,beg_row,beg_col," ");
  1152.                     (void) wrefresh(fromwindow);
  1153.                     (void) wmove(fromwindow,beg_row,beg_col);
  1154.                     (void) wrefresh(fromwindow);
  1155.                     *fld_ptr = '\0';
  1156.                     offset = -1;
  1157.                 }
  1158.                 else {
  1159. /* Mimic a Unix */  (void) wmove (fromwindow,beg_row,(beg_col + offset + 1));
  1160. /* stty echoe   */  (void) wprintw(fromwindow, " ");
  1161.                     (void) wprintw(fromwindow, " ");
  1162.                     (void) wrefresh(fromwindow);
  1163.                     (void) wmove (fromwindow,beg_row,(beg_col + offset + 1));
  1164.                     (void) wrefresh(fromwindow);
  1165.                     *(fld_ptr + (offset + 1)) = '\0';
  1166.                 }
  1167.             }
  1168.             if (offset == 0) {
  1169.                 (void) clr_fld(size,fromwindow,beg_row,beg_col);
  1170.                 (void) wmove (fromwindow, beg_row, (beg_col + 1));
  1171.                 (void) wrefresh (fromwindow);
  1172.             }
  1173.             if (ch != '\b') {
  1174.                 *(fld_ptr + offset) = ch;
  1175.                 (void) wmove (fromwindow,beg_row,(beg_col + offset));
  1176.                 (void) waddch(fromwindow,ch);
  1177.                 (void) wrefresh (fromwindow);
  1178.             }
  1179.         }
  1180.         if (fill_flag == 'y') {
  1181.             if (size > 1) {
  1182.                 *(fld_ptr + offset) = '\0';
  1183.             }
  1184.         }
  1185. #ifndef XENIX
  1186.         (void) echo();
  1187. #endif
  1188.         break;
  1189.     }
  1190. }
  1191.  
  1192. clr_fld (size, fromwindow, beg_row, beg_col)
  1193.  
  1194. int size;
  1195. int beg_row; 
  1196. int beg_col;
  1197. char *fromwindow;
  1198.  
  1199. {
  1200.     int i;
  1201.  
  1202.     for (i = (beg_col+1); i < (beg_col+size); ++i) {
  1203.         (void) mvwprintw(fromwindow,beg_row,i," ");
  1204.     }
  1205.     (void) wrefresh(fromwindow);
  1206. }
  1207.  
  1208. \Rogue\Monster\
  1209. else
  1210.   echo "will not over write ./getword.c"
  1211. fi
  1212. echo "Finished archive 1 of 1"
  1213. exit
  1214.