home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  17.8 KB  |  901 lines

  1. /*
  2.  *  Copyright (c) 1992, 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <limits.h>
  8.  
  9.  
  10. #ifdef unix
  11. # include <sys/types.h>
  12. # include <sys/stat.h>
  13. # include <sys/file.h>
  14. # ifdef SYSV
  15. #   include <sys/fcntl.h>
  16. # endif
  17. #endif
  18.  
  19. #ifdef __os2__
  20. #include <fcntl.h>
  21. #include <io.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24.  
  25.  typedef struct HOLDFEA *PHOLDFEA;
  26.  PHOLDFEA QueryEAs (char *name);
  27.  int WriteEAs (char *name, PHOLDFEA pHoldFEA);
  28. #endif
  29.  
  30. #ifdef msdos
  31. #include <fcntl.h>
  32. #include <io.h>
  33. #include <sys/stat.h>
  34. #endif
  35. #ifdef __GO32__
  36. #include <fcntl.h>
  37. #endif
  38.  
  39. /* Was anything missed? */
  40. #ifndef O_RDONLY
  41. #ifdef VMS
  42. #include <file.h>
  43. #else
  44. #include <fcntl.h>
  45. #endif
  46. #endif
  47.  
  48. #include "config.h"
  49. #include "buffer.h"
  50. #include "file.h"
  51. #include "misc.h"
  52. #include "sysdep.h"
  53. #include "paste.h"
  54. #include "slang.h"
  55. #include "ins.h"
  56. #include "ledit.h"
  57.  
  58. #if defined (msdos) || defined (__os2_16__)
  59. #define MAX_LINE_LEN 1024
  60. #else
  61. #define MAX_LINE_LEN 64 * 1024
  62. #endif
  63.  
  64. #ifdef VMS
  65. static int vms_max_rec_size;
  66. #include <stat.h>
  67. #include <rms.h>
  68. static int VMS_write_rfm_fixed;
  69. int vms_stupid_open(char *file)
  70. {
  71.    struct stat s;
  72.    char rat_buf[80], rfm_buf[80], mrs_buf[40], *rfm = "var";
  73.    unsigned short mode = 0, c;
  74.    int ret;
  75.  
  76.    VMS_write_rfm_fixed = 0;
  77.  
  78.    strcpy(rfm_buf, "rfm=");
  79.    
  80.    
  81.    if (0 == stat(file, &s))
  82.      {
  83.     strcpy(rat_buf, "rat");
  84.     c = s.st_fab_rat;
  85.     if (c & FAB$M_FTN)  strcat(rat_buf, ",ftn");
  86.     if (c & FAB$M_CR)  strcat(rat_buf, ",cr");
  87.     if (c & FAB$M_PRN)  strcat(rat_buf, ",prn");
  88.     if (c & FAB$M_BLK)  strcat(rat_buf, ",blk");
  89.     if (rat_buf[3] != 0) rat_buf[3] = '='; else *rat_buf = 0;
  90.  
  91.     c = s.st_fab_rfm;
  92.     switch(c)
  93.       {
  94.        case FAB$C_UDF:  rfm = "udf"; break;
  95.        case FAB$C_FIX:  
  96.          rfm = "fix"; 
  97.          VMS_write_rfm_fixed = 1;
  98.          break;
  99.        case FAB$C_VAR:  rfm = "var"; break;
  100.        case FAB$C_VFC:  rfm = "vfc"; break;
  101.        case FAB$C_STM:  rfm = "stm"; break;
  102.        case FAB$C_STMLF:  rfm = "stmlf"; break;
  103.        case FAB$C_STMCR:  rfm = "stmcr"; break;
  104.       }
  105.     mode = s.st_mode & 0777;
  106.      }
  107.    else strcpy (rat_buf, "rat=cr");
  108.    
  109.    strcat(rfm_buf, rfm);
  110.    
  111.    if (vms_max_rec_size <= 0) vms_max_rec_size = 255;
  112.    sprintf(mrs_buf, "mrs=%d", vms_max_rec_size);
  113.       
  114.    if (*rfm == 's')               /* stream */
  115.      {
  116.     ret = creat(file, mode, rfm_buf);
  117.      }
  118.    else
  119.      {
  120.     if (*rat_buf) ret = creat(file, mode, rfm_buf, mrs_buf, rat_buf);
  121.     else ret = creat(file, mode, rfm_buf, mrs_buf);
  122.      }
  123.    if (ret >= 0) chmod(file, mode);
  124.    return ret;
  125. }
  126. #endif
  127.  
  128. int Require_Final_Newline = 0;
  129.  
  130. /* 0 = read, 1 = write , 2 = append... */
  131. int sys_open(char *file, int acces)
  132. {
  133.    int fp = -1;
  134.    int flags;
  135.    unsigned int mode;
  136. #ifdef VMS
  137.    char *p, neew[256];
  138. #endif
  139.    
  140. #ifdef O_BINARY
  141.     mode = O_BINARY;
  142. #else
  143.     mode = 0;
  144. #endif
  145.  
  146.    flags = file_status(file);
  147.    if ((flags < 0) || (flags > 1)) return(fp);
  148.    
  149.    /* on VMS I cheat since I do not want to deal with RMS at this point */
  150. #ifdef VMS
  151.    VMS_write_rfm_fixed = 0;
  152.    strcpy(neew, file);
  153.    p = neew; while (*p) if (*p == ';') *p = 0; else p++;
  154.    
  155.    if (acces == 0) fp = open(file, O_RDONLY, "ctx=rec","mbf=8","mbc=32","rop=RAH","shr=upi,get,put");
  156.    else if (acces == 1)
  157.      {
  158.     fp = vms_stupid_open(neew);
  159.      }
  160.    
  161.    else if (acces == 2) fp = open(file, O_WRONLY | O_APPEND | O_CREAT | mode);
  162. #else
  163.    
  164.    switch(acces)
  165.      {
  166.       case 0: flags =  O_RDONLY; 
  167.     break;
  168.       case 1: flags =  O_WRONLY | O_CREAT | O_TRUNC;
  169.     break;
  170.       case 2: flags =  O_WRONLY | O_CREAT | O_APPEND; 
  171.     break;
  172.       default: return(fp);
  173.      }
  174.    
  175.    flags |= mode;
  176.    
  177. #if defined (msdos) || defined (__os2__)
  178.    fp = open(file, flags, S_IREAD | S_IWRITE); 
  179. #else
  180.    fp = open(file, flags, 0666); 
  181. #endif
  182. #endif /* VMS */
  183.    return(fp);
  184. }
  185.  
  186. /* Leaves Point at last line inserted */
  187. /* returns -1 if unable to open file,
  188.            -2 if memory allocation error
  189.            otherwise returns number of lines read */
  190.  
  191. char *file_type(char *file)
  192. {
  193.    char *p, *psave;
  194.    if ((file == (char *) NULL) || (*file == 0)) return( (char *) NULL);
  195.  
  196.    file = extract_file(file);
  197.    p = file; while (*p != 0) p++;
  198.    psave = p;
  199.    while((p != file) && (*p != '.')) p--;
  200.    if (*p == '.') p++;
  201.    if (p == file) return(psave); else return(p);
  202. }
  203.  
  204. void set_file_modes()
  205. {
  206.    char *type;
  207.  
  208.    if (CBuf == NULL) return;
  209.    CBuf->c_time = sys_time();
  210.    if (CBuf->file[0])
  211.      {
  212.     CBuf->flags |= AUTO_SAVE_BUFFER;
  213.     CBuf->hits = 0;
  214.     type = file_type(CBuf->file);
  215.      }
  216.    else type = (char *) NULL;
  217.  
  218.    if (type == (char *) NULL) CBuf->modes = NO_MODE;
  219.    else if (SLang_run_hooks("mode_hook", type, NULL));
  220.    else CBuf->modes = NO_MODE;
  221. }
  222.  
  223. int read_file(char *file)
  224. {
  225.    int fp;
  226.    int n, status;
  227.  
  228.    if ((fp = sys_open(file, 0)) < 0)
  229.      {
  230.     status = file_status(file);
  231.     if (!status) return(-1);  /* file does not exist */
  232.     return(-2); /* exists but not readable */
  233.      }
  234.  
  235.    n = read_file_pointer(fp);
  236.    close(fp);
  237.    eob();
  238.    if ('\n' == *(CLine->data + Point)) make_line(2);
  239.  
  240.    VFile_Mode = VFILE_TEXT;
  241.    return n;
  242. }
  243.  
  244. int insert_file_pointer(VFILE *vp)
  245. {
  246.    int n = 0;
  247.    unsigned int num;
  248.    unsigned char *vbuf;
  249.    
  250.    Suspend_Screen_Update = 1;
  251.    while(NULL != (vbuf = (unsigned char *) vgets(vp, &num)))
  252.      {
  253.     n++;
  254.     if (SLang_Error) break;
  255.     quick_insert(vbuf, (int) num);
  256.      }
  257.    return(n);
  258. }
  259.  
  260. int insert_file(char *file)
  261. {
  262.    VFILE *vp;
  263.    int n;
  264.    
  265.    if (NULL == (vp = vopen(file, 0, VFile_Mode))) return(-1);
  266.    n = insert_file_pointer(vp);
  267.    vclose(vp);
  268.    return(n);
  269. }
  270.  
  271.  
  272. #define WRITE jed_write1
  273.  
  274. #if defined(unix) || defined(VMS)
  275. #define BUFSIZE 0x7FFF
  276. #else
  277. #define BUFSIZE 512
  278. #endif
  279.  
  280. static int Output_Buffer_Size = BUFSIZE;
  281. static char output_buffer[BUFSIZE];
  282. static char *output_bufferp;
  283. static char *output_bufferp_max;
  284.  
  285.  
  286. /* definitely perform the write.  Return number of chars written */
  287. int jed_write1(int fd, char *b, unsigned int n)
  288. {
  289. #if !defined(msdos) || defined(__WATCOMC__)
  290.    int len;
  291.    unsigned int total = 0;
  292.    while (total < n)
  293.      {
  294.     if ((len = write (fd, b, n - total)) <= 0) break;
  295.     total += (unsigned int) len;
  296.     b += len;
  297.      }
  298.    return total;
  299. #else
  300.    int num = -1;
  301.    asm mov ah, 40h
  302.    asm mov bx, fd
  303.    asm mov cx, n
  304.    asm push ds
  305.    asm lds dx, dword ptr b
  306.    asm int 21h
  307.    asm pop ds
  308.    asm jc L1
  309.    asm mov num, ax               /* number of bytes written */
  310.    L1: 
  311.    return(num);
  312. #endif
  313. }
  314.  
  315.  
  316.  
  317. /* RMS wants to start a NEW record after a write so just forget it! */
  318. /* maybe do write-- return number of chars possibly written */
  319.  
  320. int jed_write(int fd, char *b, unsigned int n)
  321. {
  322.    int num, max, nl_flag = 0;
  323.    unsigned int nsave = n;
  324.    int cr_flag = CBuf->flags & ADD_CR_ON_WRITE_FLAG;
  325.  
  326. #ifdef VMS
  327.    if (VMS_write_rfm_fixed == 0)
  328.      {
  329.     output_bufferp = output_buffer;
  330.     return jed_write1(fd, b, n);
  331.      }
  332.    
  333. #endif
  334.  
  335.    /* amount of space left in buffer */
  336.    /* copy whats in b to the output buffer */
  337.    while(n)
  338.      {
  339.     num = (int) (output_bufferp_max - output_bufferp);
  340.     if (n > num)
  341.       {
  342.          max = num;
  343.          MEMCPY(output_bufferp, b, max);
  344.          output_bufferp += max;
  345.       }
  346.  
  347.     else if (cr_flag && 
  348.          (*(b + (n - 1)) == '\n') && (VFile_Mode == VFILE_TEXT))
  349.       {
  350.          max = n - 1;
  351.          MEMCPY(output_bufferp, b, max);
  352.          output_bufferp += max;
  353.          *output_bufferp++ = '\r';
  354.          max++;
  355.  
  356.          /* can only write the \r */
  357.          if (n == num) nl_flag = 1; else *output_bufferp++ = '\n';
  358.       }
  359.     else
  360.       {
  361.          max = n;
  362.          MEMCPY(output_bufferp, b, max);
  363.          output_bufferp += max;
  364.       }
  365.     
  366.     if (output_bufferp == output_bufferp_max)
  367.       {
  368.          output_bufferp = output_buffer;
  369.          if (Output_Buffer_Size != WRITE(fd, output_buffer, Output_Buffer_Size)) return(-1);
  370.          if (nl_flag)
  371.            {
  372.           nl_flag = 0;
  373.           *output_bufferp++ = '\n';
  374.            }
  375.       }
  376.     b += max;
  377.     n -= max;
  378.      }
  379.    return(nsave);
  380. }
  381.  
  382. /* returns -1 on failure */
  383. int write_region_to_fp(int fp)
  384. {
  385.    register int pnt, len;
  386.    register Line *first, *last;
  387.    int last_pnt, n = 0;
  388.    char *err = "Write Failed!";
  389.  
  390. #ifndef VMS
  391.    char nl = '\n';
  392. #endif
  393.    
  394.    output_bufferp = output_buffer;
  395.    output_bufferp_max = output_buffer + BUFSIZE;
  396.    Output_Buffer_Size = BUFSIZE;
  397.  
  398. #ifdef VMS
  399.    if (VMS_write_rfm_fixed && (vms_max_rec_size <= BUFSIZE))
  400.      {
  401.     Output_Buffer_Size = vms_max_rec_size;
  402.      }
  403.    else VMS_write_rfm_fixed = 0;
  404. #endif   
  405.    if (!check_region(&Number_One)) return(-1);
  406.    last = CLine; last_pnt = Point;
  407.  
  408.    pop_mark(&Number_One);
  409.    first = CLine; pnt = Point;
  410.  
  411.    /* first should never be null without hitting last first.  If this
  412.       ever happens, check_region failed. */
  413.    while (first != last)
  414.      {
  415.     len = first->len - pnt;
  416.     if (len != jed_write(fp, (char *) (first->data + pnt), len))
  417.       {
  418.          msg_error(err);
  419.       }
  420.     
  421.     /* This goes here inside the loop because it is possible for external
  422.        events to set error_buffer */
  423.     pnt = 0;
  424.     if (SLang_Error) break;
  425.     first = first->next;
  426.     n++;
  427.      }
  428.  
  429.    if (!SLang_Error && (last_pnt != 0))
  430.      {
  431.     len = last_pnt - pnt;
  432.     if (len != jed_write(fp, (char *) (last->data + pnt), len))
  433.       {
  434.          msg_error(err);
  435.       }
  436.     n++;
  437.      }
  438. #ifndef VMS
  439.    if ((Require_Final_Newline) && (CBuf->end == last))
  440.      {
  441.     eob(); if (Point) jed_write(fp, &nl, 1);
  442.      }
  443. #endif
  444.    
  445.  
  446.    /* Now flush output buffer if necessary */
  447.    
  448.    len = (int) (output_bufferp - output_buffer);
  449.    if (!SLang_Error && len) if (len != WRITE(fp, output_buffer, len))
  450.      {
  451.     msg_error(err);
  452.      }
  453.    
  454.    output_bufferp = output_buffer;
  455.  
  456.    
  457.    pop_spot();
  458.    VFile_Mode = VFILE_TEXT;
  459.    if (SLang_Error) return(-1);
  460.    return(n);
  461. }
  462.  
  463. /* write current buffer to open file pointer. Return number of lines */
  464.  
  465. int write_region(char *file)
  466. {
  467.    int fp;
  468.    int n;
  469.    char msg[256];
  470.  
  471.    if (!check_region(&Number_Zero)) return(-1);
  472.    if ((fp = sys_open(file, 1)) < 0)
  473.      {
  474.     sprintf(msg, "Unable to open %s for writing.", file);
  475.     msg_error(msg);
  476.     return(-1);
  477.      }
  478.    n = write_region_to_fp(fp);
  479.    close(fp);
  480.  
  481.    return(n);
  482. }
  483.  
  484.  
  485.  
  486. /* returns -1 on failure and number of lines on success */
  487.  
  488. int write_file(char *file)
  489. {
  490.    Mark *m;
  491.    int n = -1;
  492.    int fnl;
  493.    
  494.    
  495. #ifdef VMS
  496.    register Line *l = CBuf->beg;
  497.    register int len = 0, max = 0;
  498.    
  499.    while (l != NULL)
  500.      {
  501.     len = l->len;
  502.     if (len > max) max = len;
  503.     l = l->next;
  504.      }
  505.    vms_max_rec_size = max;
  506. #endif
  507.    
  508.    push_spot();
  509.    bob();
  510.    push_mark();  m = CBuf->marks;
  511.    eob();
  512.    fnl = Require_Final_Newline;
  513.    if (CBuf->flags & BINARY_FILE) 
  514.      {
  515.     VFile_Mode = VFILE_BINARY;
  516.     Require_Final_Newline = 0;
  517.  
  518. #ifdef VMS
  519.     vms_max_rec_size = 512;
  520. #endif
  521.      }
  522.  
  523.    n = write_region(file);
  524.    
  525.    Require_Final_Newline = fnl;
  526.    VFile_Mode = VFILE_TEXT;
  527.    if (m == CBuf->marks) pop_mark(&Number_Zero);
  528.    pop_spot();
  529.    return(n);
  530. }
  531.  
  532. int append_to_file(char *file)
  533. {
  534.    int fp;
  535.    int n;
  536.  
  537.    if ((fp = sys_open(file, 2)) < 0) return(-1);
  538.    n = write_region_to_fp(fp);
  539.    close(fp);
  540.    check_buffers();
  541.    return(n);
  542. }
  543.  
  544. int make_autosave_filename(char *save, char *dir, char *file)
  545. {
  546.    char *s;
  547.    int dat;
  548.  
  549.    if (*file == 0) return(0);
  550.       
  551.    
  552.    if (SLang_run_hooks("make_autosave_filename", dir, file) && !SLang_Error)
  553.      {
  554.     if (SLang_pop_string(&s, &dat)) return(0);
  555.     strncpy(save, s, 254);
  556.     save[255] = 0;
  557.     if (dat == 1) SLFREE(s);
  558.      }
  559.    else
  560.      {
  561. #ifdef unix
  562.     sprintf(save, "%s#%s#", dir, file);
  563. #else
  564. #if defined (msdos) || defined (__os2__)
  565.     sprintf(save, "%s#%s", dir, file);
  566. #else
  567.     sprintf(save, "%s_$%s;1", dir, file);
  568. #endif
  569. #endif
  570.      }
  571.    return(1);
  572. }
  573.  
  574. int write_file_with_backup(char *dir, char *file)
  575. {
  576.    char neew[256]; char save[256];
  577.    int n;
  578.    int mode, do_mode;
  579.    short uid, gid;
  580. #ifndef VMS
  581.    char *old;
  582.    int ok = 0, bu, do_free = 0;
  583. #endif
  584. #ifdef __os2__
  585.    PHOLDFEA EAs;
  586. #endif
  587.    
  588.    if (*file == 0) return(-1);
  589.  
  590.    sprintf(neew, "%s%s", dir, file);
  591.    
  592.    if (((CBuf->flags & AUTO_SAVE_BUFFER) == 0)
  593.        || !make_autosave_filename(save, dir, file)) *save = 0;
  594.  
  595.    do_mode = sys_chmod(neew, 0, &mode, &uid, &gid);
  596.    if ((do_mode < 0) ||  (do_mode > 1)) return(-1);
  597. #ifndef VMS
  598.    
  599. #ifdef __os2__
  600.    EAs = QueryEAs (neew);
  601. #endif
  602.    
  603.    bu = 1;
  604.    if (((CBuf->flags & NO_BACKUP_FLAG) == 0)
  605.        && SLang_run_hooks("make_backup_filename", dir, file))
  606.      {
  607.     if (((bu = !SLang_pop_string(&old, &do_free)) != 0) && (*old))
  608.       {
  609.          unlink(old);
  610.          ok = !rename(neew, old);
  611.       }
  612.      }
  613. #endif
  614.    
  615.    if (-1 != (n = write_file(neew)))
  616.      {
  617.     if (*save)
  618.       {
  619.          sys_delete_file(save);
  620.       }
  621.          
  622.     if (do_mode) /* must be an existing file, so preserve mode */
  623.       {
  624. #ifdef msdos
  625.          /* Want the archive bit set since this is a new version */
  626.          mode |= 1 << 5;
  627. #endif
  628.          sys_chmod (neew, 1, &mode, &uid, &gid);
  629. #ifdef __os2__
  630.          WriteEAs (neew, EAs);
  631. #endif
  632.       }
  633.     /* This is for NFS time problems */
  634.     CBuf->c_time = sys_file_mod_time(neew);
  635.     /* CBuf->c_time = sys_time(); */
  636.      }
  637. #ifndef VMS
  638.    else if (ok && bu && *old) rename(old, neew); /* error -- put it back */
  639.    if ((do_free == 1) && bu) SLFREE(old);
  640. #endif
  641.    return(n);
  642. }
  643.  
  644. /* warning-- this saves on the narrowed part of buffer.
  645.    Here, I widen first.  I need a save_restriction type of thing because
  646.    I do not narrow back.
  647.    */
  648. void auto_save_buffer(Buffer *b)
  649. {
  650.    char tmp[256];
  651.    Buffer *old_buf;
  652.    unsigned int vfm = VFile_Mode;
  653.    
  654.    if (b == NULL) return;
  655.    b->hits = 0;
  656.    if ((b->narrow != NULL) || !(b->flags & BUFFER_TRASHED)) return;
  657.  
  658.    old_buf = CBuf;
  659.    switch_to_buffer(b);
  660.    
  661.    if (b->flags & BINARY_FILE)  VFile_Mode = VFILE_BINARY; 
  662.    else VFile_Mode = VFILE_TEXT;
  663.  
  664.    if (b->flags & AUTO_SAVE_BUFFER)
  665.      {
  666.     if (make_autosave_filename(tmp, b->dir, b->file))
  667.       {
  668.          flush_message("autosaving..."); 
  669.          sys_delete_file(tmp);
  670.          write_file(tmp);
  671.          message("autosaving...done");
  672.       }
  673.       }
  674.    else if (b->flags & AUTO_SAVE_JUST_SAVE)
  675.      {
  676.     if (write_file_with_backup(b->dir, b->file) >= 0)
  677.       {
  678.          b->flags &= ~BUFFER_TRASHED;
  679.       }
  680.      }
  681.    switch_to_buffer(old_buf);
  682.    VFile_Mode = vfm;
  683. }
  684.  
  685. void auto_save_all()
  686. {
  687.     Buffer *b;
  688.  
  689.    if (NULL == (b = CBuf)) return;
  690.    do
  691.      {
  692.     while (b->narrow != NULL) widen_buffer(b);
  693.     if (*b->file != 0) auto_save_buffer(b);
  694.     b = b->next;
  695.      }
  696.    while (b != CBuf);
  697. }
  698.  
  699. #ifdef unix
  700. #ifndef __GO32__
  701. int is_link(char *f, char *f1)
  702. {
  703.    struct stat s;
  704.    int l;
  705.    int is_dir = 0;
  706.    char work[256];
  707.    
  708.    l = strlen(f) - 1;
  709.    if ((f[l] == '/') && (l > 1))
  710.      {
  711.     strcpy(work, f);
  712.     is_dir = 1;
  713.     f = work;
  714.     f[l] = 0;
  715.      }
  716.    
  717.  
  718.    if (( lstat(f, &s) == -1 ) 
  719.        /* || ((s.st_mode & S_IFMT)  S_IFLNK)) */
  720.        || (((s.st_mode & S_IFMT) & S_IFLNK) == 0))
  721.      return(0);
  722.    
  723.    if (-1 == (l = readlink(f, f1, 512))) return(0);
  724.    if (is_dir) f1[l++] = '/';
  725.    f1[l] = 0;
  726.    return(1);
  727. }
  728.  
  729. /* we do not worry about the dir--- only the filename */
  730. char *expand_link(char *f)
  731. {
  732.    char work[256], lnk[256];
  733.    char *d = expand_filename(f);
  734.    
  735.    if (is_link(d, lnk)) 
  736.      {
  737.     strcpy(work, d);
  738.     *(extract_file(work)) = 0;
  739.     strcat(work, lnk);
  740.     d = expand_filename(work);
  741.      }
  742.    
  743.    return (d);
  744. }
  745.  
  746. #endif
  747. #endif
  748.  
  749. void visit_file(char *dir, char *file)
  750. {
  751. #ifndef __os2__
  752.    if (strcmp(file, CBuf->file) || strcmp(dir, CBuf->dir))
  753. #else
  754.    if (strcmpi(file, CBuf->file) || strcmp(dir, CBuf->dir))
  755. #endif
  756.      {
  757.     if (NULL == find_buffer(file)) strcpy(CBuf->name, file); 
  758.     else uniquely_name_buffer(file);
  759.    
  760.     strcpy(CBuf->dir, dir);
  761.     strcpy(CBuf->file, file);
  762.      }
  763.    /* We have already taken care of this in write buffer function.
  764.     */
  765.    /* CBuf->c_time = sys_time(); */
  766.  
  767.    check_buffers();
  768. }
  769.  
  770.  
  771. char *dir_file_merge(char *dir, char *file)
  772. /* 
  773.  * returns result of merging dir with file. If file is empty, dir is
  774.  * considered to be whole file.
  775.  */
  776. {
  777.    char name[512];
  778.  
  779.    strcpy (name, dir);
  780.    if ((file != NULL) && *file)
  781.      {
  782.     fixup_dir(name);
  783.     strcat(name, file);
  784.      }
  785.    return expand_filename(name);
  786. }
  787.  
  788. int file_status(char *file)
  789. /*
  790.  *  Returns a coded integer about file.  If the file does not exist, 0 is
  791.  *  returned.  Meaning:
  792.  *
  793.  *     2 file is a directory
  794.  *     1 file exists
  795.  *     0 file does not exist.
  796.  *    -1 no access.
  797.  *    -2 path invalid
  798.  *    -3 unknown error
  799.  */
  800. {
  801.    int mode = 0;
  802.    short uid, gid;
  803.    return sys_chmod(file, 0, &mode, &uid, &gid);
  804. }
  805.  
  806. int file_changed_on_disk(char *file)
  807. {
  808.    unsigned long t;
  809.    Buffer *buf;
  810.    if (NULL == (buf = find_file_buffer(file))) return(0);
  811.    t = sys_file_mod_time(file);
  812.    return(t > buf->c_time);
  813. }
  814.  
  815. int file_time_cmp(char *file1, char *file2)
  816. {
  817.    unsigned long t1, t2;
  818.    
  819.    t1 = sys_file_mod_time(file1);
  820.    t2 = sys_file_mod_time(file2);
  821.     /*These times are modification  times from 1970.  Hence, the bigger 
  822.      * number represents the more recent change.  Let '>' denote 
  823.      * 'more recent than'.  This function returns:
  824.      *       1:  file1 > file2
  825.      *       0:  file 1 == file2
  826.      *       -1: otherwise. 
  827.      *    So:
  828.      */
  829.    if (t1 == t2) return(0);
  830.    if (t1 > t2) return(1); 
  831.    return(-1);
  832. }
  833.  
  834. void auto_save(void)
  835. {
  836.    auto_save_buffer(CBuf);
  837. }
  838.  
  839. void check_buffer(Buffer *b)
  840. {
  841.    if ((*b->file != 0)
  842.        && file_changed_on_disk(dir_file_merge(b->dir, b->file)))
  843.      {
  844.     b->flags |= FILE_MODIFIED;
  845.      }
  846.    else b->flags &= ~FILE_MODIFIED;
  847. }
  848.  
  849. void check_buffers()
  850. {
  851.    Buffer *b = CBuf;
  852.    do
  853.      {
  854.     check_buffer(b);
  855.     b = b->next;
  856.      }
  857.    while (b != CBuf);
  858. }
  859.  
  860. void set_file_trans(int *mode)
  861. {
  862.    if (*mode) VFile_Mode = VFILE_BINARY; else VFile_Mode = VFILE_TEXT;
  863. }
  864.  
  865. int read_file_pointer(int fp)
  866. {
  867.    int n = 1;
  868.    unsigned int num;
  869.    unsigned char *vbuf;
  870.    VFILE *vp;
  871.    
  872.    if (SLang_Error || (vp = vstream(fp, MAX_LINE_LEN, VFile_Mode)) == NULL) return(-1);
  873.    
  874.    if (NULL == (vbuf = (unsigned char *) vgets(vp, &num))) return(0);
  875.    
  876.    if (CLine->space < num)
  877.      {
  878.     remake_line(CLine->len + num + 1);
  879.      }
  880.    MEMCPY((char *) CLine->data, (char *) vbuf, (int) num);
  881.    CLine->len = num;
  882.    
  883.    while(NULL != (vbuf = (unsigned char *) vgets(vp, &num)))
  884.      {
  885.     n++;
  886.     if ((num == 1) && (*vbuf == '\n')) make_line(num); else make_line(num + 1);
  887.     MEMCPY((char *) CLine->data, (char *) vbuf, (int) num);
  888.     CLine->len = num;
  889.     if (SLang_Error) break;
  890.      }
  891.    if (vp->buf != NULL) SLFREE(vp->buf);
  892.    
  893.    if (vp->cr_flag) CBuf->flags |= ADD_CR_ON_WRITE_FLAG;
  894.    else CBuf->flags &= ~ADD_CR_ON_WRITE_FLAG;
  895.    
  896.    SLFREE(vp);
  897.    return n;
  898. }
  899.  
  900.  
  901.