home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / sources / wanted / 5065 < prev    next >
Encoding:
Text File  |  1992-11-16  |  22.5 KB  |  1,142 lines

  1. Path: sparky!uunet!pipex!warwick!uknet!mcsun!sunic!seunet!dakotaS!idanm!pmod
  2. From: pmod@pfbs.philips.se (Par-Mikael Odsater)
  3. Newsgroups: comp.sources.wanted
  4. Subject: HEX Editor
  5. Message-ID: <807@idanm.pfbs.philips.se>
  6. Date: 16 Nov 92 11:33:41 GMT
  7. Sender: news@pfbs.philips.se
  8. Organization: Digital Equipment BCFI AB, Sweden
  9. Lines: 1131
  10.  
  11. I give you the HEX Editor.
  12.  
  13. This is the Makefile
  14. --------------------- CUT HERE -------------------------------------
  15. hex:    hex.c
  16.     $(CC) hex.c $(CFLAGS) -lcurses -o hex
  17. --------------------- CUT HERE -------------------------------------
  18.  
  19. This is the hex.c
  20. --------------------- CUT HERE -------------------------------------
  21. /*----------------------------------------------------------------------------*/
  22. /* Program: hex.c                                  */
  23. /* Date:    27-nov-1988                                  */
  24. /* Desc:    Hex editor source                              */
  25. /* Author:  Dominic Alston                              */
  26. /* Version: 2.4                                      */
  27. /* Revision history:                                   */
  28. /*    25-jan-1989  dom: Added terminal independant code                   */
  29. /*      30-jan-1989  dom: Redesigned screen, added features                   */
  30. /*    03-feb-1989  dom: Modified code.                      */
  31. /*    04-feb-1989  dom: Added own mmi routines                              */
  32. /*      05-feb-1989  dom: Version 2 Increment 0 release finished.             */
  33. /*      06-feb-1989  dom: Fixed goto out of band chars being accepted         */
  34. /*      20-feb-1989  dom: Added version print and readonly feature            */
  35. /*      23-feb-1989  dom: Added screen refresh.                               */
  36. /*----------------------------------------------------------------------------*/
  37.  
  38. #include <sys/types.h>
  39. #include <curses.h>
  40. #include <fcntl.h>
  41. #include <ctype.h>
  42. #include <errno.h>
  43. #include <signal.h>
  44. #include <sys/stat.h>
  45.  
  46. #define VERSION_STAMP "2.4"
  47. #define PAGESIZE 1280
  48. #define BUFSIZE 256
  49. #define READING    0
  50. #define WRITING    1
  51. #define GOTO 2
  52. #define DBUFF_SIZE 32
  53. #define FBUFF_SIZE 16
  54. #define X_PRODUCT 30
  55. #define Y_PRODUCT 0
  56. #define X_MENU1    0
  57. #define Y_MENU1    2
  58. #define X_MENU2    0
  59. #define Y_MENU2    3
  60. #define X_STATUS 0
  61. #define Y_STATUS 5
  62. #define X_FORMAT 76
  63. #define X_POSITION 19
  64. #define X_PROMPT 0
  65. #define Y_PROMPT 6
  66. #define X_INPUT 9
  67. #define X_FIND 9
  68. #define Y_FIND 6
  69. #define X_HEX 0
  70. #define Y_HEX 7
  71. #define X_CHAR 52
  72. #define Y_CHAR 7
  73. #define X_EXIT 0
  74. #define Y_EXIT 23
  75. #define X_VERB 36
  76. #define Y_VERB 5
  77. #define CTRL(c) ((c) & 037)
  78. #define _KEY_EXIT 'q'
  79. #define ENTER '\n'
  80. #define KEY_ESC    '\033'
  81. #define KEY_TAB    '\t'    
  82.  
  83. char *pos_get();
  84. int ctrlc_ast();
  85. static int ch;                /* buffer for single character read           */
  86. static char page[PAGESIZE];    /* buffer for screen display              */
  87. static char *hptr;        /* pointer to page for hex display          */
  88. static char *cptr;        /* pointer to page for character display      */
  89. static char buf[BUFSIZE];    /* buffer for input i/o                  */
  90. static char *bptr;        /* pointer to buf                  */
  91. static char pos[9];        /* buffer for character format of position    */
  92. static char find_buff[FBUFF_SIZE]; /* buffer holding the string for searching */
  93. static int find_length;         /* size of string searched for                */
  94. static char disp_buff[DBUFF_SIZE]; /* buffer holding the search string during */
  95. static int disp_length;
  96. static char hexchars[] = "0123456789ABCDEF";
  97. static char head1[] = "                      Hexpert [v2.4 (c)1988 Dominic Alston]                     ";
  98. static char r_head2[] = 
  99.     "Options: <Up-arrow>  =Page-up    <g>=Goto-position  <c> =Char-find  <q>=Exit   "; /* apm 27/1/85*/
  100. static char r_head3[] = 
  101.     "         <Down-arrow>=Page-down  <h>=Hex-find       <^l>=Refresh              ";
  102. static char head2[] = 
  103.     "Options: <Up-arrow>  =Page-up    <g>=Goto-position  <c>=Char-find  <q> =Exit"; /* apm 27/1/85*/
  104. static char head3[] = 
  105.     "         <Down-arrow>=Page-down  <e>=Edit-buffer    <h>=Hex-find   <^l>=Refresh";
  106. static char head4[] = 
  107.     "Status-  Position: 00000000   Mode: View   File: ";
  108. static char head5[] = 
  109.     "Options: <Enter>=Write-buffer  <Tab>=Toggle hex/char edit                      "; /* apm 27/1/85 */
  110. static char head6[] = 
  111.     "         <Esc>  =Restore buffer & goto view mode                               ";
  112. static char head7[] =
  113.     "Options: <Enter>=Do-search       <Left-arrow>= Move-left                       "; /* apm 27/1/85 */
  114. static char head8[] =
  115.     "         <Esc>  =Goto view mode  <Right-arrow>=Move-right                      ";
  116. static char edit1[] =
  117.     "Options: <Enter>=Goto-position   <Left-arrow>=Move-left                        ";
  118. static char edit2[] =
  119.     "         <Esc>  =Goto view mode  <Right-mode>=Move-right                       ";
  120. static char msg1[] = "pattern not found!";
  121. static char usage_bnr[]=
  122.     "Usage: hex [-vr] 'file'";
  123. static char version_bnr[]=
  124.     "HEXPERT V%s, Dominic Alston..\n";
  125. static char error1[] = "internal error - hex unpaired!";
  126. static int x,y;        /* screen co-ordinates                         */
  127. static int input;    /* file descriptor for input file              */
  128. static int mode;    /* current mode of use                      */
  129. static int readonly;    /* true if input file is read only              */
  130. static int save_flags;    /* dump of terminal info while in RAW mode           */
  131. static int bytes_written;
  132. static int bytes_read;
  133. static char hex_find;    /* true if find mode is currently hex              */
  134. static long position;    /* displacement of current buffer in input file          */
  135. static long lastbyte;   /* displacement of end of file     (Mod 256)            */
  136. static struct stat filedata; /* statistics of the input file,gives file size  */
  137. static int bool_hexfind=FALSE;
  138. extern char *optarg;
  139.  
  140. main(argc,argv)
  141. int argc;
  142. char *argv[];
  143. {
  144.     int c;
  145.     char filenm[80];
  146.  
  147.     while ((c=getopt(argc,argv,"vr:"))!=EOF)
  148.         switch(c)
  149.         {
  150.             case 'v':
  151.                 fprintf(stderr,version_bnr,
  152.                               VERSION_STAMP);
  153.                 exit(-1);
  154.             case 'r':
  155.                 readonly=TRUE;
  156.                 strcpy(filenm,optarg);
  157.                 break;    
  158.             default:
  159.                 fprintf(stderr,"%s\n",usage_bnr);
  160.                 exit(-1);
  161.         }
  162.     if (argc==1)
  163.     {
  164.         fprintf(stderr,"%s\n",usage_bnr);
  165.         exit(-1);
  166.     }
  167.     else
  168.         initialise(filenm[0]==0?argv[1]:filenm);
  169.     toplevel();
  170.     closedown();
  171. }
  172.  
  173. static initialise(filename)
  174. char *filename;
  175. {
  176.     register int i,j; 
  177.     char *ptr;
  178.  
  179.     /* Open file for read & write, if this fails                          */
  180.     /* open file for reading, if fail exit.                              */
  181.     if ((input=open(filename,O_RDWR))==-1) 
  182.         if ((input=open(filename,O_RDONLY))==-1)
  183.         {
  184.             perror(filename);
  185.             exit(-1);
  186.         }
  187.         else
  188.             readonly=TRUE;
  189.     init_term();        /* init curses terminfo                  */
  190.     signal(SIGINT,ctrlc_ast);   /* signal handler for contol c           */
  191.     /* Read the file statistics to find  the                              */
  192.     /* file size and put it in 'lastbyte',                                */
  193.     /* after adjusting to a multiple of 256                               */
  194.     if ((fstat(input,&filedata))==0)
  195.         lastbyte=(filedata.st_size-1) & 0x7fffff00;
  196.     else
  197.         lastbyte = 0;
  198.     /* Clear the display buffer.                               */
  199.     hptr=page;
  200.     for (i=0; i<PAGESIZE; i++) 
  201.         *hptr++=' ';
  202.     attron(A_REVERSE);
  203.     addstr(head1);
  204.     attroff(A_REVERSE);
  205.     toplev_headings();
  206.     mvaddstr(Y_STATUS, X_STATUS,head4);
  207.     /* Display the input file name.                                  */
  208.     i=strlen(filename);
  209.     ptr=filename;
  210.     if (i>33) 
  211.         i=33;
  212.     for (j=0; j<i; j++)
  213.         addch(*ptr++);
  214.     /* Read and display the first 256 bytes                              */
  215.     if (readonly)
  216.     {
  217.         attron(A_BOLD);
  218.         mvaddstr(Y_STATUS,72,"Readonly");
  219.         attroff(A_BOLD);
  220.     }
  221.     refresh();
  222.     position = 0;
  223.     lseek(input,position,0);
  224.     display();
  225.     mode = READING;
  226.     hex_find = FALSE;
  227.     find_length = 0;
  228.     put_prompt();
  229.     refresh();
  230. }
  231.  
  232. static display()
  233. {
  234.     int num;
  235.     register int i;
  236.     int j;
  237.     int jlimit;
  238.     char *pptr;
  239.  
  240.     hptr = page;
  241.     cptr = (hptr + 52);
  242.     bptr = buf;
  243.     pos_print();
  244.     move(Y_HEX, X_HEX);
  245.     if (((num=read(input,buf,BUFSIZE))!=EOF) && (num!=0)) 
  246.     {
  247.         if (num<BUFSIZE) 
  248.         {
  249.             for (i=0; i<PAGESIZE; i++) 
  250.                 *hptr++ = ' ';
  251.             hptr=page;
  252.         }
  253.         for (i=0; i<num; i+=16) 
  254.         {
  255.             jlimit=((num-i)>=16)?16:num-i;
  256.             for (j=0; j<jlimit; j++) 
  257.             {
  258.                 *hptr++=hexchars[(*bptr>>4) & 0xf];
  259.                 *hptr++=hexchars[*bptr & 0xf];
  260.                 *hptr++=' ';
  261.                 *cptr++=((*bptr)>0x1f &&
  262.                      (*bptr)<0x7f?*bptr:'.');
  263.                 bptr++;
  264.             }
  265.             *((cptr-jlimit)+80)='\n';
  266.             hptr+=32;
  267.             cptr=(hptr+52);
  268.         }
  269.     }
  270.     else
  271.         for(i=0; i<PAGESIZE; i++) 
  272.             *hptr++=' ';
  273.     bytes_read=num;
  274.     move(Y_HEX,X_HEX);
  275.     hptr=page;
  276.     for (i=0; i<PAGESIZE; i++)
  277.         addch(*hptr++);
  278.     bytes_written=i; 
  279.     if (bytes_written!=PAGESIZE) 
  280.         closedown();
  281.     put_prompt();
  282.     refresh();
  283. }
  284.  
  285. static closedown()
  286. {
  287.     reset_term();
  288.     exit(0);
  289. }
  290.  
  291. static toplevel()
  292. {
  293.     int num_read;
  294.  
  295.     while ((ch=getch())!=_KEY_EXIT)
  296.     {
  297.         clrtoeol();
  298.         refresh();
  299.         switch(ch) 
  300.         {
  301.             case CTRL('l'):
  302.                 clearok(curscr,TRUE);
  303.                 doupdate();
  304.                 break;
  305.             case KEY_HOME:
  306.                 if (position!=0)
  307.                 {
  308.                     position=0;
  309.                     lseek(input,position,0);
  310.                     display();
  311.                 }
  312.                 else
  313.                     beep();
  314.                 break;
  315.             case KEY_DOWN:    
  316.                 if (position != lastbyte) 
  317.                 {
  318.                     if ((position += 256) > lastbyte)
  319.                         position = lastbyte;
  320.                     lseek(input,position,0);
  321.                     display();
  322.                 }
  323.                 else
  324.                     beep();
  325.                 break;
  326.             case KEY_UP:
  327.                 if (position != 0)
  328.                 {
  329.                     position -= 256;
  330.                     if (position < 0)
  331.                         position = 0;
  332.                     lseek(input,position,0);
  333.                     display();
  334.                 }
  335.                 else
  336.                     beep();
  337.                 break;
  338.             case 'g':
  339.             case 'G':
  340.                 mode=GOTO;
  341.                 if (get_position())
  342.                 {
  343.                     lseek(input,position,0);
  344.                     display();
  345.                 }
  346.                 else
  347.                     pos_print();    
  348.                 toplev_headings();
  349.                 mode=READING;
  350.                 break;
  351.             case 'e':
  352.             case 'E':
  353.                 if (readonly) 
  354.                 {
  355.                     beep();
  356.                     move(6,9);
  357.                     refresh();
  358.                 }
  359.                 else
  360.                     editbuffer();
  361.                 break;
  362.             case 'c':
  363.             case 'C':
  364.             case 'h':
  365.             case 'H':
  366.                 if ((ch=='c') || (ch=='C'))
  367.                     hex_find=FALSE;
  368.                 else
  369.                     hex_find=TRUE;
  370.                 if (get_string()==1)
  371.                     find_string();
  372.                 toplev_headings();
  373.                 break;
  374.             default:    
  375.                 beep();
  376.                 break;
  377.         }
  378.     }
  379. }
  380.  
  381. static get_position()
  382. {
  383.     char num[9];
  384.     char *ptr1,*ptr2;
  385.     int status;
  386.     long posit;
  387.     register int i;
  388.  
  389.     edit_headings();
  390.     posit=0;
  391.     ptr1=num;
  392.     ptr2=pos;
  393.     for (i=0; i<9; i++) 
  394.         (*(ptr1++))=(*(ptr2++));
  395.     move(Y_STATUS,10);
  396.     disp_length=7;
  397.     if ((status=get_str(stdscr,Y_STATUS,X_POSITION,num,'0',8))==-1)
  398.         return(FALSE);
  399.     for (i=0; i<8; i++) 
  400.     {
  401.         posit=(posit<<4)+(num[i] & 0xf);
  402.         if (num[i]>'9') 
  403.             posit+=9;
  404.     }
  405.     if (posit<0) 
  406.         posit=0;
  407.     if (posit<=lastbyte) 
  408.         position=posit;
  409.     else 
  410.         position=lastbyte;
  411.     return(TRUE);
  412. }
  413.  
  414. static trace(a)
  415. char a;
  416. {
  417.     move(1,70);
  418.     addch(a);
  419.     refresh();
  420. }
  421.  
  422. static pos_print()
  423. {
  424.     char *ptr;
  425.  
  426.     ptr=pos+7;
  427.     *ptr--=hexchars[(position & 0xf)];
  428.     *ptr--=hexchars[((position>>4) & 0xf)];
  429.     *ptr--=hexchars[((position>>8) & 0xf)];
  430.     *ptr--=hexchars[((position>>12) & 0xf)];
  431.     *ptr--=hexchars[((position>>16) & 0xf)];
  432.     *ptr--=hexchars[((position>>20) & 0xf)];
  433.     *ptr--=hexchars[((position>>24) & 0xf)];
  434.     *ptr--=hexchars[((position>>28) & 0xf)];
  435.     *(ptr+8)=0;
  436.     mvaddstr(Y_STATUS,X_POSITION,pos);
  437. }
  438.  
  439. static editbuffer()
  440. {
  441.     /* Display edit headings    */
  442.     mvaddstr(Y_MENU1, X_MENU1,head5);
  443.     mvaddstr(Y_MENU2, X_MENU2,head6);
  444.     mvaddstr(Y_VERB, X_VERB,"Edit");
  445.     hex_ed();
  446.     mode = READING;
  447.         toplev_headings();
  448. }
  449.  
  450. /* read_headings: Display read headings */
  451. static toplev_headings()
  452. {
  453.     if (readonly)
  454.     {
  455.         mvaddstr(Y_MENU1, X_MENU1,r_head2);
  456.         mvaddstr(Y_MENU2, X_MENU2,r_head3);
  457.     }
  458.     else
  459.     {
  460.         mvaddstr(Y_MENU1, X_MENU1,head2);
  461.         mvaddstr(Y_MENU2, X_MENU2,head3);
  462.     }
  463.     mvaddstr(Y_VERB, X_VERB,"View");
  464.     move(Y_PROMPT, X_INPUT);
  465.     refresh();
  466. }
  467.  
  468. static char_ed()  /* Entered from hex_ed() when 'TAB' read. */
  469. {
  470.     char *ptr;
  471.     char *hptr;
  472.     char c1,c2;
  473.     int xx;
  474.     int num_read;
  475.  
  476.     /* get byte by mapping on to physical scale from screen scale         */
  477.     ptr=page+(y-7)*80+x;
  478.     move(y,x);
  479.     refresh();
  480.     do
  481.     {
  482.         ch=getch();
  483.         if ((ch)>=0x20 && (ch)<0x7f) 
  484.         {
  485.             addch(ch);
  486.             refresh();
  487.             *ptr = ch;
  488.             c1 = ch & 0xf;
  489.             c2 = (ch >> 4) & 0xf;
  490.             xx = (x - 52) * 3;
  491.             hptr = (ptr - x) + xx;
  492.             *hptr++ = hexchars[c2];
  493.             *hptr   = hexchars[c1];
  494.             move(y,xx);
  495.             addch(*--hptr);
  496.             addch(*++hptr);
  497.             refresh();
  498.             if (x == 67) 
  499.                 if (y < 22) 
  500.                 {
  501.                     ptr +=65;
  502.                     x = 52;
  503.                     y++;
  504.                 }
  505.                 else     
  506.                 {
  507.                     ptr = page + 52;
  508.                     x = 52;
  509.                     y = 7;
  510.                 }
  511.             else     
  512.             {
  513.                 ptr++;
  514.                 x++;
  515.             }
  516.         }
  517.         else if (ch==KEY_RIGHT)
  518.             if (x==67) 
  519.             {
  520.                 if (y<22) 
  521.                 {
  522.                     ptr+=65;
  523.                     x=52;
  524.                     y++;
  525.                 }
  526.                 else     
  527.                 {
  528.                     ptr=page+52;
  529.                     x=52;
  530.                     y=7;
  531.                 }
  532.             }
  533.             else     
  534.             {
  535.                 ptr++;
  536.                 x++;
  537.             }
  538.         else if (ch == KEY_LEFT)
  539.             if (x == 52) 
  540.             {
  541.                 if (y > 7) 
  542.                 {
  543.                     ptr -= 65;
  544.                     x = 67;
  545.                     y--;
  546.                 }
  547.                 else    
  548.                 {
  549.                     ptr += 1215;
  550.                     x = 67;
  551.                     y = 22;
  552.                 }
  553.             }
  554.             else    
  555.             {
  556.                 ptr--;
  557.                 x--;
  558.             }
  559.         else if (ch == KEY_UP) 
  560.             if (y > 7)    
  561.             {
  562.                 ptr -=80;
  563.                 y--;
  564.             }
  565.             else    
  566.             {
  567.                 ptr +=1200;
  568.                 y = 22;
  569.             }
  570.         else if (ch == KEY_DOWN) 
  571.             if (y < 22) 
  572.             {
  573.                 ptr +=80;
  574.                 y++;
  575.             }
  576.             else    
  577.             {
  578.                 ptr -=1200;
  579.                 y = 7;
  580.             }
  581.         else if (ch == KEY_ESC) 
  582.         {
  583.             lseek(input,position,0);
  584.             display();
  585.         }
  586.         else if ((ch == ENTER) || (ch == KEY_TAB))
  587.             /* do nothing */ ;
  588.         else 
  589.             beep();
  590.         move(y,x);
  591.         refresh();
  592.     }
  593.     while ((ch!=ENTER) && 
  594.                (ch!=KEY_TAB) && 
  595.                (ch!=KEY_ESC));
  596.     if (ch==ENTER) 
  597.     {
  598.         hex_to_buf();
  599.         lseek(input,position,0);
  600.         write(input,buf,bytes_read);
  601.     }
  602.     mode=READING;
  603. }
  604.  
  605. static hex_ed()
  606. {
  607.     char *ptr;
  608.     int num_read;
  609.  
  610.     ptr=page;
  611.     x=X_HEX;
  612.     y=Y_HEX;
  613.     move(y,x);
  614.     refresh();
  615.     do
  616.     {
  617.         ch=getch();
  618.         if (isxdigit(ch)) 
  619.         {
  620.             addch(toupper(ch));
  621.             refresh();
  622.             *ptr = ch;
  623.             {
  624.                 char *cptr,c1,c2;
  625.                 int xx;
  626.  
  627.                 if ((x%3) == 1)
  628.                     cptr = ptr - 1;
  629.                 else
  630.                     cptr = ptr;
  631.                 c1 = *cptr++;
  632.                 c2 = *cptr;
  633.                 if (c1 > '9')
  634.                     c1 = (c1 + 9) & 0xf;
  635.                 else
  636.                     c1 = c1 & 0xf;
  637.                 if (c2 > '9')
  638.                     c2 = (c2 + 9) & 0xf;
  639.                 else
  640.                     c2 = c2 & 0xf;
  641.                 c1 = (c1 << 4) + c2;
  642.                 xx = (x/3) + 52;
  643.                 move(y,xx);
  644.                 refresh();
  645.                 if ((c1>=0x20) && (c1<0x7f))
  646.                     addch(c1);
  647.                 else
  648.                     addch('.');
  649.                 refresh();
  650.             }
  651.             ptr++;
  652.             x++;
  653.             if (((x+1)%3)==0) 
  654.             {
  655.                 if (x==47) 
  656.                 {
  657.                     if (y<22) 
  658.                     {
  659.                         ptr+=33;
  660.                         x=0;
  661.                         y++;
  662.                     }
  663.                     else 
  664.                     {
  665.                         ptr=page;
  666.                         x=0;
  667.                         y=7;
  668.                     }
  669.                 }
  670.                 else    
  671.                 {
  672.                     ptr++;
  673.                     x++;
  674.                 }
  675.             }
  676.         }
  677.         else if (ch==KEY_RIGHT) 
  678.         {
  679.             ptr++;
  680.             x++;
  681.             if (((x+1)%3)==0) 
  682.                 if (x==47) 
  683.                     if (y<22) 
  684.                     {
  685.                         ptr+=33;
  686.                         x=0;
  687.                         y++;
  688.                     }
  689.                     else 
  690.                     {
  691.                         ptr=page;
  692.                         x=0;
  693.                         y=7;
  694.                     }
  695.                 else 
  696.                 {
  697.                     ptr++;
  698.                     x++;
  699.                 }
  700.         }
  701.         else if (ch==KEY_LEFT) 
  702.             if (x==0) 
  703.             {
  704.                 if (y>7) 
  705.                 {
  706.                     ptr -= 34;
  707.                     x = 46;
  708.                     y--;
  709.                 }
  710.                 else    
  711.                 {
  712.                     ptr += 1246;
  713.                     x = 46;
  714.                     y = 22;
  715.                 }
  716.             }
  717.             else    
  718.             {
  719.                 ptr--;
  720.                 x--;
  721.                 if (((x+1)%3)==0) 
  722.                 {
  723.                     ptr--;
  724.                     x--;
  725.                 }
  726.             }
  727.         else if (ch == KEY_UP) 
  728.             if (y > 7) 
  729.             {
  730.                 ptr -= 80;
  731.                 y--;
  732.             }
  733.             else     
  734.             {
  735.                 ptr += 1200;
  736.                 y = 22;
  737.             }
  738.         else if (ch == KEY_DOWN) 
  739.             if (y < 22) 
  740.             {
  741.                 ptr += 80;
  742.                 y++;
  743.             }
  744.             else 
  745.             {
  746.                 ptr -= 1200;
  747.                 y = 7;
  748.             }
  749.         else if (ch == KEY_ESC) 
  750.         {
  751.             lseek(input,position,0);
  752.             display();
  753.         }
  754.         else if (ch==ENTER);
  755.         else if (ch==KEY_TAB) 
  756.         { 
  757.             x = (x/3) + 52;
  758.             char_ed();
  759.             x = (x-52) * 3;
  760.             ptr = page + (y-7)*80 + x;
  761.         }
  762.         else 
  763.             beep();
  764.         move(y,x);
  765.         refresh();
  766.     }
  767.     while (ch!=ENTER && ch!=KEY_ESC);
  768.     if (ch==ENTER) 
  769.     {
  770.         hex_to_buf();
  771.         lseek(input,position,0);
  772.         write(input,buf,bytes_read);
  773.     }
  774. }
  775.  
  776. static hex_to_buf()
  777. {
  778.     char c1,c2;
  779.     int i;
  780.     int j;
  781.  
  782.     hptr = page;
  783.     bptr = buf;
  784.     for (i=0;i<16;i++) 
  785.     {
  786.         for (j=0;j<16;j++) 
  787.         {
  788.             c1 = *hptr++;
  789.             if (c1 > '9')
  790.                 c1 = (c1 + 9) & 0xf;
  791.             else
  792.                 c1 = c1 & 0xf;
  793.             c2 = *hptr++;
  794.             if (c2 > '9')
  795.                 c2 = (c2 + 9) & 0xf;
  796.             else
  797.                 c2 = c2 & 0xf;
  798.             *bptr++ = (c1 << 4) + c2;
  799.             hptr++;
  800.         }
  801.         hptr += 32;
  802.     }
  803. }
  804.  
  805.  
  806. static int get_string()
  807. {   
  808.     mvaddstr(Y_MENU1, X_MENU1,head7);
  809.     mvaddstr(Y_MENU2, X_MENU2,head8);
  810.     mvaddstr(Y_VERB, X_VERB,"Find");
  811.     attron(A_BOLD);
  812.     mvaddstr(6,0,"search criteria: ");
  813.     attroff(A_BOLD);
  814.     if ((bool_hexfind && !hex_find) || (!bool_hexfind && hex_find))
  815.     {
  816.         if (hex_find)
  817.             bool_hexfind=TRUE;
  818.         else if (!hex_find)
  819.             bool_hexfind=FALSE;
  820.         find_length=0;
  821.         disp_buff[0]=0;
  822.     }
  823.     if (hex_find)
  824.     {
  825.         buftoh(disp_buff,find_buff,find_length);
  826.         disp_length=find_length*2;
  827.     }
  828.     else
  829.         buftobuf(disp_buff,find_buff,disp_length=find_length);
  830.     if ((disp_length=get_str(stdscr,6,17,disp_buff,'.',
  831.          hex_find?DBUFF_SIZE:FBUFF_SIZE))==-1)
  832.     {
  833.         put_prompt();
  834.         return(FALSE);
  835.     }
  836.     else if (disp_length==0 && hex_find)
  837.         disp_length=find_length*2;
  838.     else if (disp_length==0 && !hex_find)
  839.         disp_length=find_length;
  840.     set_string();
  841.     return(TRUE);
  842. }
  843.  
  844. /* set_string: set up the string for return */
  845. static set_string()
  846. {
  847.     if (hex_find)
  848.     {
  849.         htobuf(find_buff,disp_buff,disp_length);
  850.         find_length=disp_length/2;
  851.     }
  852.     else 
  853.         buftobuf(find_buff,disp_buff,find_length=disp_length);
  854. }
  855.  
  856. /* buftoh: Converts input buffer to hexadecimal display in output string.
  857.  *         String length is used since zero is legitimate.
  858.  */
  859. static buftoh(out_string, in_string, in_size)
  860. char *in_string, *out_string;
  861. int in_size;
  862. {    
  863.     register int i;
  864.  
  865.     for (i=0; i < in_size; i++)
  866.     {
  867.         char ch = *in_string++;
  868.         *out_string++ = hexchars[(ch >> 4) & 0xf]; /* [ch/16]; */
  869.         *out_string++ = hexchars[ ch & 0xf]; /* [ch%16]; */
  870.     }
  871. }
  872.  
  873. /* htobuf: converts hexadecimal display to binary. String length is used
  874.  *         and only hexadecimal pairs are handled.
  875.  */
  876. static htobuf(out_string, in_string, in_size)
  877. char *in_string, *out_string;
  878. int in_size;
  879. {   
  880.     char i;
  881.     int h_value, c_value;
  882.     int byte_val;
  883.  
  884.     if (in_size%2 != 0) 
  885.     {
  886.         put_prompt();
  887.         addstr(error1);
  888.         beep();
  889.         refresh();
  890.         return;
  891.     }
  892.     for (i=0; i < in_size; i++)
  893.     {   
  894.         if ((h_value = *in_string++) >= '0' && h_value <= '9')
  895.                 c_value = h_value -'0';
  896.         else (c_value = 10 + (h_value & 0xf) - ('a' & 0xf));    
  897.         if (!(i%2))
  898.             byte_val = c_value * 16;
  899.         else 
  900.             *out_string++ = byte_val + c_value;
  901.     }
  902. }
  903.  
  904. /* buftobuf: Copy buffer to buffer. Not quite strncopy since zero is valid
  905.  *           and not a terminator.
  906.  */
  907. static buftobuf(out_string,in_string,in_size)
  908. char *in_string,*out_string;
  909. int in_size;
  910. {   
  911.     register int i;
  912.  
  913.     for (i=0; i<in_size; i++)
  914.         (*(out_string++))=(*(in_string++));
  915. }
  916.  
  917. /* find_string: Locates the string which has been specified by the user.
  918.  *        The search is carried out cyclically locating the string
  919.  *        specified at the beginning of the buffer. If the string is
  920.  *        not found we tell the user with a friendly message.
  921.  */
  922. int find_string()
  923. {   
  924.     long start_pos=position; /* hold start position to stop cyclic search */
  925.     int inc_length;
  926.     /* the number of start points for search in one buffer full */
  927.     int num_read; /* number read in this read */
  928.     int found_it=0;
  929.  
  930.     position ++;  /* make sure we move ahead */
  931.     inc_length=BUFSIZE-find_length;
  932.     /* search to the end of the file */
  933.     while (filedata.st_size>=position+find_length && found_it!=1)
  934.     {   
  935.         lseek(input,position,0);
  936.         num_read=read(input,buf,BUFSIZE);
  937.         if (search(buf,&position,num_read-find_length)) 
  938.             found_it=1;
  939.     } 
  940.     /* if still not found then search from beginning              */
  941.     if (found_it!=1)
  942.     {
  943.         position=0;
  944.         while (position<=start_pos && found_it!=1)
  945.         {   
  946.             lseek(input,position,0);
  947.             num_read=read(input,buf,BUFSIZE);
  948.             if (search(buf,&position,position+inc_length<start_pos?
  949.                      (int)inc_length:(int)(start_pos-position)))
  950.                 found_it=1;
  951.         }
  952.     }
  953.     if (found_it!=1)
  954.     {
  955.         put_prompt();
  956.         addstr(msg1);
  957.         beep();
  958.         refresh();
  959.         position = start_pos;
  960.         lseek(input,position,0);
  961.         return;
  962.     }
  963.     lseek(input, position, 0);
  964.     display();
  965. }
  966.  
  967. /* search: Search for the field described by find_buff and find_length in 
  968.  *         the parameter buf incrementing start as far as size.
  969.  *         Returning true if the string is found.
  970.  */
  971. int search(buf,start,size)
  972. char *buf;
  973. long *start;
  974. int size;
  975. {   
  976.     int i, j;
  977.  
  978.     i = 0;
  979.     j = -1;
  980.     while (i != find_length && j++ < size) /* loop through buffer */
  981.     {   
  982.         for (i=0; i<find_length && *(find_buff+i)==*(buf+i); i++)
  983.         /* loop through string (no body) */ ;
  984.         buf++;
  985.         }
  986.     *start+=j;
  987.     return (i==find_length);
  988. }
  989.  
  990. /* initialise term..                                  */
  991. init_term()
  992. {
  993.     initscr();        /* init curses terminfo                      */
  994.     keypad(stdscr,TRUE);    /* allow keypad use                      */
  995.     noecho();        /* set terminal to noecho                     */
  996.     cbreak();        /* raw input                           */
  997. }
  998.  
  999. /* reset term to the way it was                                  */
  1000. reset_term()
  1001. {
  1002.     nocbreak();
  1003.     echo();
  1004.     endwin();
  1005. }
  1006.  
  1007. /* get string routine                                  */
  1008. int get_str(wnd,row,col,str,filler,str_size)
  1009. WINDOW *wnd;
  1010. int row,col,str_size;
  1011. char filler;
  1012. char *str;
  1013. {
  1014.     char out_buff[40];
  1015.     int ccol=0,c,erase_flg=0;
  1016.     register int i;
  1017.     int leave=FALSE;
  1018.     int status=0;
  1019.  
  1020.     for (i=0; i<str_size; i++)    /* paste filler to field          */
  1021.         mvwaddch(wnd,row,col+i,filler);
  1022.     /* print contents of str                          */
  1023.     for (i=0; i<disp_length; i++)
  1024.         mvwaddch(wnd,row,col+i,str[i]);
  1025.     wmove(wnd,row,col);            /* move to field start          */
  1026.     wrefresh(wnd);                /* refresh whats been done    */
  1027.     while (!leave)
  1028.     {
  1029.         c=wgetch(wnd);
  1030.         switch(c)
  1031.         {
  1032.             case '\n':
  1033.             case '\r':
  1034.                 leave=TRUE;
  1035.                 break;
  1036.             case KEY_HOME:
  1037.                 ccol=0;
  1038.                 wmove(wnd,row,col+ccol);
  1039.                 refresh();
  1040.                 break;
  1041.             case CTRL('h'):
  1042.                 if (ccol>0)
  1043.                 {
  1044.                     if (--ccol<0)
  1045.                         ccol=0;
  1046.                           mvwaddch(wnd,row,col+ccol,filler);
  1047.                     wmove(wnd,row,col+ccol);
  1048.                     *(str+ccol)=' ';
  1049.                     wrefresh(wnd);
  1050.                 }
  1051.                 else
  1052.                     beep();
  1053.                 break;
  1054.             case KEY_ESC:            /* if escape pressed */
  1055.                 status=(char)-1;
  1056.                 leave=TRUE;
  1057.                 break;
  1058.             case KEY_LEFT:
  1059.                 erase_flg=1;
  1060.                 if (ccol>0)
  1061.                 {
  1062.                     if (--ccol<0)
  1063.                         ccol=0;
  1064.                               wmove(wnd,row,col+ccol);
  1065.                     wrefresh(wnd);
  1066.                 }
  1067.                 else
  1068.                     beep();
  1069.                 break;
  1070.             case KEY_RIGHT:
  1071.                 if (ccol<str_size-1)
  1072.                 {
  1073.                     if (++ccol>str_size)
  1074.                         ccol=str_size;
  1075.                         wmove(wnd,row,col+ccol);
  1076.                     wrefresh(wnd);
  1077.                 }
  1078.                 else
  1079.                     beep();
  1080.                 break;    
  1081.             default:            /* other chars         */
  1082.                 if ((((hex_find || mode==GOTO) && 
  1083.                         isxdigit(c)) || 
  1084.                     ((!hex_find && mode!=GOTO) && 
  1085.                     (c>=0x20 && c<0x7f))) &&
  1086.                     ccol<str_size)
  1087.                 {
  1088.                     if (erase_flg==0)
  1089.                         for (i=0; i<str_size; i++)
  1090.                         {
  1091.                             mvwaddch(wnd,row,col+i,
  1092.                                 filler);
  1093.                             str[i]=' ';
  1094.                         }
  1095.                     mvwaddch(wnd,row,col+ccol,c);
  1096.                     wrefresh(wnd);
  1097.                     *(str+ccol)=c;
  1098.                     if (++ccol>str_size)
  1099.                         ccol=str_size;
  1100.                 }
  1101.                 else
  1102.                     beep();
  1103.                 break;
  1104.         }
  1105.         erase_flg=1;
  1106.     }
  1107.     if (status==0)
  1108.         status=ccol;
  1109.     return(status);
  1110. }
  1111.  
  1112. ctrlc_ast(sig)
  1113. int sig;
  1114. {
  1115.     if (sig==SIGINT)
  1116.         closedown();
  1117.     else
  1118.         signal(SIGINT,ctrlc_ast);
  1119. }
  1120.  
  1121. put_prompt()
  1122. {
  1123.     move(6,0);
  1124.     clrtoeol();
  1125.     attron(A_BOLD);
  1126.     mvaddstr(Y_PROMPT, X_PROMPT,"command> ");
  1127.     attroff(A_BOLD);
  1128. }
  1129.  
  1130. edit_headings()
  1131. {
  1132.     mvaddstr(Y_MENU1, X_MENU1,edit1);
  1133.     mvaddstr(Y_MENU2, X_MENU2,edit2);
  1134.     mvaddstr(Y_VERB, X_VERB,"Goto");
  1135. }
  1136. --------------------- CUT HERE -------------------------------------
  1137. --
  1138.  Par-Mikael (P-M) Odsater           | Digital Equipment BCFI AB
  1139.                                     | Box 904
  1140.  pmod@pfbs.philips.se               | S-175 29 Jarfalla, Sweden 
  1141.  ..!mcsun!seunet!dakotaS!pmod@pfbs  | Phone: +46 8 7594928, Fax: +46 8 7398676
  1142.