home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / most423.zip / file.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  10KB  |  456 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4.  
  5. #ifndef toupper
  6. #define toupper(c)    ((c)-'a'+'A')
  7. #endif
  8.  
  9. #ifndef VMS
  10. #include <fcntl.h>
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <unistd.h>
  14. #else
  15. #include <types.h>
  16. #include <stat.h>
  17. #include <stdlib.h>
  18. #endif
  19.  
  20. #ifndef O_RDONLY
  21. #define O_RDONLY 0
  22. #endif
  23.   
  24. #include "externs.h"
  25. #include "file.h"
  26. #include "keym.h"  
  27. #include "buffer.h"
  28. #include "window.h"
  29. #include "display.h"
  30. #include "sysdep.h"
  31.  
  32. char *FILE_RING[500];
  33. char C_DIR[256];                 /* current working dir */
  34. int NUM_FILES;
  35.  
  36. extern int SCREEN_WIDTH;
  37.  
  38. int insert_file(char *file)
  39. {
  40.     struct stat st;
  41.     int size = 0, fd;
  42. #ifdef VMS
  43.    unsigned recsz = 512;
  44.    extern int stat(char *, struct stat *);
  45. #endif
  46.  
  47.     if (file[0] == '\0')        /* assume stdin */
  48.       {
  49.           fd = 0;
  50.           strcpy(BUF->file,"(Standard Input)");
  51.       }
  52.     else
  53.       {
  54.           if (stat(file, &st)) return(-1);
  55.           if (st.st_mode & S_IFDIR)  /* S_IFDIR = 0040000 */
  56.             {
  57. #ifndef VMS
  58.            return get_dir(file);
  59. #else
  60.                 return(-1);
  61. #endif                
  62.             }
  63.           size = st.st_size;
  64. #ifdef VMS 
  65.          recsz = st.st_fab_mrs;
  66.      if (recsz <= 255) recsz = 255;
  67.           /* VMS share options (shr=put) suggested by Henk D. Davids <hdavids@mswe.dnet.ms.philips.nl> */
  68.           /* VMS share options (shr=upi,get,put) suggested by Mark Pizzolato <mark@infocomm.com> */
  69.           fd = open(file,O_RDONLY,"ctx=rec","mbf=8","mbc=16","rop=RAH","shr=upi,get,put");
  70.           /* if (fd < 0) fd = open(file,O_RDONLY); */
  71. #else
  72.           fd = open(file,O_RDONLY);
  73. #endif          
  74.       }
  75.    
  76.    if (fd < 0) return(-1);
  77.    
  78.    if (!fd || (size <= 0)) size = 16384;
  79. #ifdef VMS
  80.    BUF->rec = recsz;
  81. #endif
  82.    BUF->fd = fd;
  83.    EOB = BEG = BUF->beg = (unsigned char *) MALLOC(size);
  84.    BUF->size = size;
  85.    
  86.    return(read_file_dsc(1));
  87. }
  88.  
  89. static int first_time_hack = 0;           /* tru if reading file for first time */
  90. /* if read something, return non zero (1) */
  91. int read_file_dsc(int many)
  92. {
  93.    int fd = BUF->fd, n = 0, i;
  94.    int dsize, size, passes = 0;
  95.    unsigned char *pos;
  96. #ifdef VMS
  97.    int recsz = BUF->rec;
  98. #endif
  99.    
  100.    if (fd < 0) return (0);
  101.    
  102.    if (fd == 0) dsize = 4 * 1024; else dsize = 16 * 1024;
  103.    
  104.    while (many--)
  105.      {
  106.     if (passes++ == 1)
  107.       {
  108.          message("reading...", 0);
  109.          put_message();
  110.       }
  111.     
  112.          
  113.     if ((fd == 0) && (BEG != EOB))
  114.       {
  115.          size = (EOB - BEG) + dsize;
  116.          
  117.          if (BUF->size > size) pos = BEG; 
  118.          else 
  119.            {
  120.           size = BUF->size + 16 * 1024;
  121.           pos = (unsigned char *) REALLOC(BEG, (unsigned) size);
  122.           BUF->size = size;
  123.            }
  124.          
  125.          C_POS = pos + (C_POS - BEG);
  126.          if ((WIN != NULL) && (WIN->buf == BUF))
  127.            {
  128.           WIN->beg_pos = pos + (WIN->beg_pos - BEG);
  129.           WIN->curs_pos = pos + (WIN->curs_pos - BEG);
  130.            }
  131.          EOB = pos + (int) (EOB - BEG);
  132.          CURS_POS = pos + (CURS_POS - BEG);
  133.          BEG = pos;
  134.       }
  135.    
  136.     pos = EOB;
  137.     n = 0;
  138. #ifdef VMS
  139.     while ((i = read(fd, (char *) pos, recsz)) > 0)
  140. #else
  141.     while ((i = read(fd, (char *) pos, dsize - n)) > 0 )
  142. #endif
  143.       {
  144.          n += i;
  145.          pos += i;
  146.          if (n >= dsize) break;
  147.       }
  148.     
  149.     if (n != 0) n = 1;
  150.     EOB = BUF->end = pos;
  151.     BUF->beg = BEG;
  152.     if ((i == 0) && (n < dsize))
  153.       {
  154.          close(fd);
  155.          BUF->fd = -1;
  156.          break;
  157.       }
  158.      }
  159.    
  160.    if (first_time_hack)
  161.      {
  162.     /* This has to go here so that count_lines will work properly */
  163.     if (!MOST_B_OPT && !MOST_K_OPT)
  164.     for (pos = BEG; (pos < (BEG + 32)) && (pos < EOB); pos++)
  165.       {
  166.          if ((*pos == 0) || (*pos > 127)) MOST_B_OPT = 1;
  167.       }
  168.      }
  169.    
  170.    NUM_LINES = count_lines(BEG,EOB);
  171.    if (passes > 1)
  172.      {
  173.     message("reading...done", 0);
  174.     put_message();
  175.     message(" ", 0);
  176.      }
  177.    return(n);
  178. }
  179.  
  180. /* This routines makes sure line n is read in. */
  181. void read_to_line(int n)
  182. {
  183.    int dn;
  184.    if (BUF->fd == -1) return;
  185.    n = n + 2 * SCREEN_HEIGHT;
  186.    dn = n - NUM_LINES;
  187.    if (dn < 0) return;
  188.    
  189.    /* dn is the number of lines to read.
  190.       Assume average of 40 bytes/line, then 40 * dn need read and we are 
  191.       reading 16K at a time.  Thus, */
  192.    dn = (40 * dn)/(16000);
  193.    if (dn == 0) dn = 1;
  194.    while ((BUF->fd != -1) && (n >= NUM_LINES)) read_file_dsc(dn);
  195. }
  196.  
  197.    
  198. int find_file(char *file)
  199. {
  200.    Buffer *new_buf, *old_buf;
  201.    int n;
  202.    static char msg[300], *msgp;
  203.     
  204.     
  205.     new_buf = create_buffer(file);
  206.     old_buf = switch_to_buffer(new_buf);
  207.    
  208.    first_time_hack = 1;
  209.     if (insert_file(file) < 0)
  210.       {
  211.      sprintf(msg, "%s failed to open.", file);
  212.      n = strlen(msg);
  213.      msgp = (char *) MALLOC((unsigned int) (n + 1));
  214.      strcpy(msgp, msg);
  215.      BUF->beg = (unsigned char *) msgp;
  216.      BUF->end = BUF->beg + n;
  217.      BUF->fd = -1;
  218.      NUM_LINES = 1;
  219.       }
  220.    first_time_hack = 0;
  221.  
  222.     BEG = BUF->beg;
  223.     EOB = BUF->end;
  224.     C_POS = BEG;
  225.     C_LINE = 1;
  226.     COLUMN = 1;
  227.     return(1);
  228. }
  229.  
  230. /* if the file is visible in a window, move to the window and return 1
  231.    else return 0 */
  232. int file_visible(char *file)
  233. {
  234.     Window *w;
  235.     w = WIN;
  236.     WIN = TOP_WIN;
  237.     do
  238.       {
  239.           if (!strcmp(WIN->buf->file,file))
  240.             {
  241.                 set_window(WIN);
  242.                 return(1);
  243.             }
  244.           WIN = WIN->next;
  245.       }
  246.     while (WIN != TOP_WIN);
  247.     WIN = w;
  248.     return(0);
  249. }
  250.  
  251.  
  252. void find_file_in_window(char *file)
  253. {
  254.     if (file_visible(file)) return;
  255.     
  256.     if (-1 == access(file,0))        /* does it exist? */
  257.       message("File not found.",1);
  258.    /* can we read it? */
  259.    /* else if (-1 == access(file,4))
  260.       message("File exists but not readable.",1); */
  261.     else 
  262.       {
  263.           free_window_buffer();
  264.           (void) find_file(file);
  265.  
  266.           window_buffer();
  267.           CURS_ROW = WIN->curs_line = 1;
  268.           CURS_POS = WIN->curs_pos = C_POS;
  269.           CURS_COL = WIN->curs_col = 1;
  270.  
  271.           redraw_window();
  272.           update_status(0);
  273.       }
  274. }
  275.  
  276.  
  277.  
  278. int next_file(int *j)
  279. {
  280.     char mbuf[132], ch, *curr_file;
  281.     int i;
  282.     
  283.     select_minibuffer();
  284.     tt_erase_line();
  285.  
  286.     for (i = 0; i < SCREEN_WIDTH; i++) MINI_BUF[i] = ' ';
  287.  
  288.     if (*j >= NUM_FILES) *j = 0;
  289.     curr_file = FILE_RING[*j];
  290.    sprintf(mbuf, "Next File (%d): %s\r", *j, curr_file);
  291.     send_string_to_term(mbuf);
  292.     while(ch = mbuf[i], ch != '\0') i++;
  293.     while(i < SCREEN_WIDTH) mbuf[i++] = ' ';
  294.     mbuf[i] = '\0';
  295.     strcpy((char *) MINI_BUF,mbuf);
  296.     while (1)
  297.       {
  298.           ch = getkey();
  299.           if (ch != '\033') break;
  300.           if (ch = getkey(), (ch != 'O') && (ch != '[')) continue;
  301.           if (ch = getkey(), (ch != 'A') && (ch != 'B')) continue;
  302.           
  303.           if (ch == 'B')
  304.             {
  305.                 if (*j == 0) *j = NUM_FILES;
  306.                 (*j)--;
  307.             }
  308.           else  /* ch == 'A' */
  309.             {
  310.                 (*j)++;
  311.                 if (*j == NUM_FILES) *j = 0;
  312.             }
  313.           curr_file = FILE_RING[*j];
  314.      sprintf(mbuf, "Next File (%d): %s", *j, curr_file);
  315.      i = strlen(mbuf);
  316.           while(i < SCREEN_WIDTH) mbuf[i++] = ' ';
  317.           mbuf[i] = '\0';
  318.           
  319.           smart_puts((char *) mbuf, (char *) MINI_BUF, SCREEN_HEIGHT, 1);
  320.      curs_bol();
  321.           strcpy((char *) MINI_BUF,mbuf);
  322.           fflush(stdout);
  323.       }
  324.    tt_erase_line();
  325.     exit_minibuffer();
  326.     MINI_BUF[0] = 0;
  327.     (*j)++;
  328.     if ((ch == 'Q') || (ch == 'q')) return(-1);
  329.     
  330.     find_file_in_window(curr_file);
  331.     return(0);
  332. }
  333.  
  334. /* extracts directory from file string, returns false if no dir */
  335. int head(char *file, char *dir)
  336. {
  337.     int n;
  338.     (void) strcpy(dir,file);
  339.     n = strlen(file) - 1;
  340. #ifdef VMS    
  341.     while((n > -1) && ((file[n] != ']') || (file[n] != ':'))) n--;
  342. #else    
  343.     while((n > -1) && file[n] != '/') n--;
  344. #endif
  345.     n++;
  346.     dir[n] = '\0';
  347.     return(n);
  348. }
  349.  
  350. /* returns a pointer to the tail of file */
  351. int tail(char *filed, char **filep)
  352. {
  353.     int n;
  354.     n = strlen(filed) - 1;
  355. #ifdef VMS    
  356.     while((n > -1) && ((filed[n] != ']') || (filed[n] != ':'))) n--;
  357. #else    
  358.     while((n > -1) && (filed[n] != '/')) n--;
  359. #endif
  360.     n++;
  361.     *filep = (filed + n);
  362.     return(n);
  363. }
  364.  
  365. /* assume path is big enough to hold new expanded version */
  366. int expand_path(char *path)
  367. {
  368. #ifndef VMS
  369.     int n;
  370. #endif
  371.     /* really cheat here-- let system do it.  The path must exist!! */
  372.     if (chdir(path))
  373.       {
  374.           message(path,1);
  375.           return(0);
  376.       }
  377.     else
  378.       {
  379.           get_cdir(path);
  380.           chdir(C_DIR);
  381. #ifndef VMS
  382.           n = strlen(path);
  383.           if (path[n-1] == '/') return(1);
  384.           path[n++] = '/'; path[n] = 0;
  385. #endif
  386.       }
  387.     return(1);
  388. }
  389.  
  390.  
  391.  
  392. void cd()
  393. {
  394.     char tmp_dir[80];
  395.     int n;
  396.     
  397.     strcpy(tmp_dir,C_DIR);
  398.     if (read_from_minibuffer("cd",C_DIR) == -1) return;
  399.     if (!chdir(C_DIR))
  400.       {
  401.           get_cdir(C_DIR);         /* expands ../ etc... */
  402.           n = strlen(C_DIR);
  403. #ifndef VMS
  404.           if (C_DIR[n-1] == '/') return;
  405.           C_DIR[n++] = '/'; C_DIR[n] = 0;
  406. #endif          
  407.           return;
  408.       }
  409.     strcpy(C_DIR,tmp_dir);
  410.     chdir(C_DIR);
  411.     message("Unable to change directory.",1);
  412. }
  413.  
  414. void user_get_file()
  415. {
  416.    char path[255], file[255], *name;
  417. #ifdef VMS
  418.    int i;
  419. #endif
  420.  
  421.    if (!head(WIN->buf->file,file))
  422.       strcpy(file,C_DIR);
  423.  
  424.     if (read_from_minibuffer("Find File",file) == -1) return;
  425.  
  426.     if (head(file,path))
  427.       {
  428.           expand_path(path);
  429.           tail(file,&name);
  430.           strcat(path,name);
  431.           name = path;
  432.       }
  433.     else name = file;
  434. #ifdef VMS
  435.    for (i=0; i < strlen(name); i++) name[i] = toupper(name[i]);
  436. #endif
  437.  
  438.    find_file_in_window(name);
  439.  
  440.     /*
  441.     **  add to file ring if successful
  442.     */
  443.     if (file_visible(name))
  444.       {
  445. #ifdef VMS
  446.           FILE_RING[NUM_FILES] = (char*) MALLOC(strlen(name) + 1);
  447.           strcpy(FILE_RING[NUM_FILES++],name);
  448. #else
  449.           FILE_RING[NUM_FILES++] = name;
  450. #endif
  451.       }
  452. }
  453.  
  454.  
  455.  
  456.