home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / workbench / fv-220 / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-17  |  9.4 KB  |  506 lines

  1. /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
  2.  *    on 6-2-91 and has gone through many revisions since then.
  3.  *      Much inspiration was given by Bill Moore, the first real user!
  4.  *
  5.  *   Author:  CHRISTOPHER D HOOPER
  6.  *
  7.  *   fv source Copyright (c) 1992 - 1998  Chris Hooper
  8.  *
  9.  *   Modification and redistribution is strictly prohibited.
  10.  *   Sale of this software above media cost is prohibited.
  11.  *
  12.  *   Except for above two restrictions, this software may be used for
  13.  *       any purpose, commercial or private.
  14.  *
  15.  *   Disclaimer:  This product is fit for no use, foreign or domestic.
  16.  *                Use implies knowledge you intend to destroy something.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #ifdef EDIT_MEMORY
  21. #    include <setjmp.h>
  22. #    include <signal.h>
  23. #endif
  24. #if defined(_OSK) || defined(_OS9000)
  25. #    include <UNIX/stat.h>
  26. #else
  27. #    include <sys/types.h>
  28. #    include <sys/stat.h>
  29. #endif
  30.  
  31. #include "main.h"
  32. #include "io.h"
  33.  
  34. #ifdef LINT
  35. #    include "lint.h"
  36. #endif
  37.  
  38. /* values for device_type */
  39. #define REGULAR_FILE 0
  40. #define BLOCK_DEVICE 1
  41. #define MEMORY       2
  42.  
  43. extern int curses_up;
  44. extern ulong inbuf_size;
  45. extern ulong cursor_address;
  46.  
  47. static int device_type = REGULAR_FILE;
  48. static FILE    *view_fp     = NULL; /* current stdio pointer for open file */
  49.  
  50. #ifdef EDIT_MEMORY
  51. static ulong memory_base;
  52. static ulong memory_end;
  53. static jmp_buf sigjmpbuf;
  54. static ulong find_memory_end();
  55. #endif
  56.  
  57. int save_changes();
  58. static void clear_buffer();
  59. static int device_end();
  60. #if !defined(OS9) && defined(EDIT_MEMORY)
  61. static void sigbadaddr();
  62. #endif
  63.  
  64.  
  65. int open_file(which)
  66. int which;
  67. {
  68.     int temp = 0;
  69.     int index;
  70.  
  71. #ifdef EDIT_MEMORY
  72.     if (*filename[which] == '<') {
  73.         char ch = '\0';
  74.  
  75.         if (sscanf(filename[which], "<%lx%c%lx>",
  76.                    &memory_base, &ch, &memory_end) == 0) {
  77.             if (!curses_up)
  78.                 fprintf(stderr, "Error: unable to interpret \"%s\"",
  79.                         filename[which]);
  80.             return(0);
  81.         }
  82.             
  83.         if (ch == ':')
  84.             memory_end += memory_base;
  85.         else if ((ch != '-') || (memory_end < memory_base))
  86.             memory_end = 0x7fffffff;
  87.  
  88.         memory_end = find_memory_end((char *) memory_base,
  89.                                      (char *) memory_end);
  90.  
  91.         view_address   = memory_base;
  92.         cursor_address = memory_base;
  93.         device_type = MEMORY;
  94.         goto mfile_end;
  95.     }
  96. #endif
  97.  
  98. #ifdef Win32
  99.     view_fp = fopen(filename[which], "rb+");
  100. #else
  101.     view_fp = fopen(filename[which], "r+");
  102. #endif
  103.  
  104.     if (force_ronly)
  105.         ronly = 1;
  106.  
  107.     if (view_fp == NULL) {
  108.         if (ronly)
  109. #ifdef Win32
  110.             view_fp = fopen(filename[which], "rb");
  111.         else if (force_write)
  112.             view_fp = fopen(filename[which], "wb");
  113.         else {
  114.             view_fp = fopen(filename[which], "rb");
  115.             if (view_fp != NULL)
  116.                 ronly = 1;
  117.         }
  118. #else
  119.             view_fp = fopen(filename[which], "r");
  120.         else if (force_write)
  121.             view_fp = fopen(filename[which], "w");
  122.         else {
  123.             view_fp = fopen(filename[which], "r");
  124.             if (view_fp != NULL)
  125.                 ronly = 1;
  126.         }
  127. #endif
  128.     }
  129.  
  130.     if (view_fp == NULL) {
  131.         if (!curses_up) {
  132.             fprintf(stderr, "Error: unable to open \"%s\"",
  133.                     filename[which]);
  134.             if (force_write || force_ronly)
  135.                 fprintf(stderr, "for %s.\n", (force_ronly ? "read" : "write"));
  136.             else
  137.                 fprintf(stderr, "\n");
  138.         }
  139.         return(0);
  140.     }
  141.  
  142.     device_type = REGULAR_FILE;
  143.  
  144. #ifdef EDIT_MEMORY
  145.     mfile_end:
  146. #endif
  147.     for (index = 0; index < 6; index++)
  148.             temp ^= file_sz[index];
  149.  
  150.     fend = file_end() & ((ulong) temp ^ 0xFECDC0CB);
  151.     return(1);
  152. }
  153.  
  154. void close_file()
  155. {
  156.     if (view_fp != NULL)
  157.         fclose(view_fp);
  158.  
  159.     view_fp = NULL;
  160.  
  161.     return;
  162. }
  163.  
  164. void extend_end(address)
  165. ulong address;
  166. {
  167. #ifdef EDIT_MEMORY
  168.     if ((device_type == MEMORY) && (address > memory_end)) {
  169.         ulong temp;
  170.         
  171.         temp = find_memory_end((char *) address, (char *) -1);
  172.         if (temp > memory_end) {
  173.             memory_end = temp;
  174.             fend = temp;
  175.         }
  176.     }
  177. #endif
  178. }
  179.  
  180. ulong file_end()
  181. {
  182.     struct stat buf;
  183.  
  184. #ifdef EDIT_MEMORY
  185.     if (device_type == MEMORY)
  186.         return(memory_end);
  187. #endif
  188.  
  189. #ifdef OS9
  190.     (void) stat(filename[filenum], &buf);
  191. #else
  192.     (void) fstat(fileno(view_fp), &buf);
  193.  
  194. #ifndef Win32
  195.     if ((buf.st_mode & S_IFMT) == S_IFBLK)
  196.         return(device_end(0));
  197.     else
  198. #endif
  199.     if ((buf.st_mode & S_IFMT) == S_IFCHR)
  200.         return(device_end(1));
  201.     else
  202. #endif
  203.         return(buf.st_size);
  204. }
  205.  
  206.  
  207. #ifndef MAXXINT
  208. #define MAXXINT (1 << 30)
  209. #endif
  210.  
  211. static int device_end(rdev)
  212. int rdev;
  213. {
  214.     ulong devsize = 512;
  215.     int smsize = 0;
  216.     int dummy;
  217.  
  218.     while (devsize < MAXXINT) {
  219.         fseek(view_fp, devsize, 0);
  220.         if (fread((void *) &dummy, 1, 1, view_fp))
  221.         devsize <<= 1;
  222.         else
  223.         break;
  224.     }
  225.  
  226.     devsize >>= 1;
  227.     smsize = devsize;
  228.  
  229.     while (smsize > 128) {
  230.         smsize >>= 1;
  231.         fseek(view_fp, devsize + smsize, 0);
  232.         if (fread((void *) &dummy, 1, 1, view_fp))
  233.         devsize += smsize;
  234.     }
  235.  
  236.     if (rdev) {
  237.         device_type = BLOCK_DEVICE;
  238.         if (devsize & 128) {
  239.          devsize += 128;
  240.          devsize &= ~511;
  241.         }
  242.         if (devsize == MAXXINT)
  243.         devsize -= 512;
  244.     } else {
  245.         if (devsize == MAXXINT)
  246.         devsize--;
  247.     }
  248.  
  249.     return(devsize);
  250. }
  251.  
  252. int refresh_buffer(force)
  253. int force;
  254. {
  255.     static ulong last_buf_size = 0;
  256.  
  257. #ifdef EDIT_MEMORY
  258. #ifdef OS9
  259.     if (device_type == MEMORY) {
  260.         if ((daddr != view_address) || (buf_size != last_buf_size)) {
  261.             if (dirty && save_changes(1)) {
  262.                 if (daddr != -1)
  263.                     view_address = daddr;
  264.                 else
  265.                     view_address = last_viewed;
  266.                 return(0);
  267.             }
  268.             daddr = view_address;
  269.  
  270.             if (_os_cpymem(1, view_address, buffer, buf_size)) {
  271.                 view_address   = last_viewed;
  272.                 cursor_address = last_viewed;
  273.                 return(1);
  274.             } else
  275.                 inbuf_size = buf_size;
  276.             last_buf_size = buf_size;
  277.         }
  278.         return(0);
  279.     }
  280. #else
  281.     /* process may not have access to requested memory */
  282.     if (device_type == MEMORY) {
  283.         if ((daddr != view_address) || (buf_size != last_buf_size)) {
  284.             if (dirty && save_changes(1)) {
  285.                 if (daddr != -1)
  286.                     view_address = daddr;
  287.                 else
  288.                     view_address = last_viewed;
  289.                 return(0);
  290.             }
  291.             daddr = view_address;
  292.  
  293.             signal(SIGSEGV, sigbadaddr);
  294.             if (setjmp(sigjmpbuf) == 0) {
  295.                 uchar *src = (uchar *) view_address;
  296.                 uchar *dst = buffer;
  297.  
  298.                 for (inbuf_size = 0; inbuf_size < buf_size; inbuf_size++)
  299.                     *dst++ = *src++;
  300.  
  301.                 signal(SIGSEGV, SIG_DFL);
  302.                 return(0);
  303.             }
  304.  
  305.             if (inbuf_size > 0)
  306.                 return(0);
  307.  
  308.             view_address   = last_viewed;
  309.             cursor_address = last_viewed;
  310.  
  311.             signal(SIGSEGV, SIG_DFL);
  312.             last_buf_size = buf_size;
  313.             return(1);
  314.         }
  315.         return(0);
  316.     }
  317. #endif
  318. #endif
  319.  
  320.     if (device_type == BLOCK_DEVICE) {
  321.         view_address &= ~511;
  322.         buf_size &= ~511;
  323.     }
  324.  
  325.     if ((daddr != view_address) || (buf_size != last_buf_size)) {
  326.         if (dirty && save_changes(1)) {
  327.             if (daddr != -1)
  328.                 view_address = daddr;
  329.             else
  330.                 view_address = last_viewed;
  331.             return(0);
  332.         }
  333.  
  334.         daddr = view_address;
  335.         if (fseek(view_fp, view_address, 0))
  336.             return(1);
  337.  
  338.         if ((inbuf_size = fread(buffer, 1, buf_size, view_fp)) == 0)
  339.             if (!force)
  340.                 return(1);
  341.         clear_buffer(inbuf_size);
  342.         last_buf_size = buf_size;
  343.     }
  344.  
  345.     return(0);
  346. }
  347.  
  348. #ifdef EDIT_MEMORY
  349. static ulong find_memory_end(start, limit)
  350. char *start;
  351. char *limit;
  352. {
  353. #ifdef OS9
  354.     return(limit);
  355. #else
  356.     int stride = 4096;
  357.     volatile int x;
  358.     char *current;
  359.  
  360.     signal(SIGSEGV, sigbadaddr);
  361.  
  362.     if (setjmp(sigjmpbuf) == 0)
  363.         for (current = start; current < limit; current += stride)
  364.             x += *current;
  365.  
  366.     signal(SIGSEGV, SIG_DFL);
  367.     return((int) current);
  368. #endif
  369. }
  370. #endif
  371.  
  372. int buf_read(pos, buffer, size)
  373. int   pos;
  374. char *buffer;
  375. int   size;
  376. {
  377.     if (pos < 0)
  378.         pos += fend;
  379.  
  380. #ifdef EDIT_MEMORY
  381. #ifdef OS9
  382.     if (device_type == MEMORY)
  383.         if (_os_cpymem(1, (void *) pos, buffer, size)) {
  384.             view_address   = last_viewed;
  385.             cursor_address = last_viewed;
  386.             return(1);
  387.         } else
  388.             return(0);
  389. #else
  390.     if (device_type == MEMORY) {
  391.         char *src = (char *) pos;
  392.         char *dst = buffer;
  393.         int copied = 0;
  394.  
  395.         /* process may not have access to requested memory */
  396.  
  397.         signal(SIGSEGV, sigbadaddr);
  398.  
  399.         if (setjmp(sigjmpbuf) != 0) {
  400.             signal(SIGSEGV, sigbadaddr);
  401.             for (copied++; copied < size; copied++) {
  402.                 src++;
  403.                 *dst++ = 0;
  404.                 if ((copied % 1024) == 0)
  405.                     break;
  406.             }
  407.         }
  408.  
  409.         for (; copied < size; copied++) {
  410.             *dst = *src;
  411.             dst++;
  412.             src++;
  413.             if ((int) src > fend)
  414.                 src = (char *) 0;
  415.         }
  416.  
  417.         signal(SIGSEGV, SIG_DFL);
  418.         return(0);
  419.     }
  420. #endif
  421. #endif
  422.  
  423.     if (pos + size > fend) {     /* block wrap over */
  424.         if (fseek(view_fp, pos, 0))
  425.             return(1);
  426.         if (fread(buffer, fend - pos, 1, view_fp) != 1)
  427.             return(1);
  428.         if (fseek(view_fp, 0, 0))
  429.             return(1);
  430.  
  431.         buffer += (fend - pos);
  432.         size   -= (fend - pos);
  433.     } else {
  434.         if (fseek(view_fp, pos, 0))
  435.             return(1);
  436.     }
  437.  
  438.     return(fread(buffer, size, 1, view_fp) != 1);
  439. }
  440.  
  441. int buf_write(pos, buffer, size)
  442. int   pos;
  443. char *buffer;
  444. int   size;
  445. {
  446. #ifdef EDIT_MEMORY
  447. #ifdef OS9
  448.     if (device_type == MEMORY)
  449.         if (_os_cpymem(1, buffer, pos, size)) {
  450.             view_address   = last_viewed;
  451.             cursor_address = last_viewed;
  452.             return(1);
  453.         } else
  454.             return(0);
  455. #else
  456.     if (device_type == MEMORY) {
  457.         char *dst = (char *) pos;
  458.         char *src = buffer;
  459.         int copied;
  460.  
  461.         /* process may not have access to requested memory */
  462.  
  463.         signal(SIGSEGV, sigbadaddr);
  464.  
  465.         if (setjmp(sigjmpbuf) == 0)
  466.             for (copied = 0; copied < size; copied++)
  467.                 *dst++ = *src++;
  468.  
  469.         signal(SIGSEGV, SIG_DFL);
  470.  
  471.         return(0);
  472.     }
  473. #endif
  474. #endif
  475.  
  476.     if (fseek(view_fp, pos, 0))
  477.         return(1);
  478.  
  479.     return(fwrite(buffer, size, 1, view_fp) == 1);
  480. }
  481.  
  482. static void clear_buffer(start)
  483. ulong start;
  484. {
  485.     int index;
  486.  
  487.     if (start & 3) {
  488.         buffer[start++] = '\0';
  489.         if (start & 3) {
  490.         buffer[start++] = '\0';
  491.         if (start & 3)
  492.             buffer[start++] = '\0';
  493.         }
  494.     }
  495.  
  496.     for (index = start >> 2; index < buf_size >> 2; index++)
  497.         ibuffer[index] = 0;
  498. }
  499.  
  500. #if defined(EDIT_MEMORY) && !defined(OS9)
  501. static void sigbadaddr()
  502. {
  503.     longjmp(sigjmpbuf, 1);
  504. }
  505. #endif
  506.