home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / file.c < prev    next >
C/C++ Source or Header  |  1993-11-17  |  44KB  |  1,394 lines

  1. /***********************************************************************/
  2. /* FILE.C - File and view related functions.                           */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1993 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 5314
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38.  
  39. /*
  40. $Header: C:\THE\RCS\file.c 1.4 1993/09/01 16:26:23 MH Interim MH $
  41. */
  42.  
  43. #include <stdio.h>
  44. #include <errno.h>
  45.  
  46. #include "the.h"
  47. #include "directry.h"
  48. #include "proto.h"
  49.  
  50. #if defined(DOS) || defined(OS2)
  51. #include <io.h>
  52. #endif
  53.  
  54. /****************** needs to be fixed *************/
  55. #ifdef GO32
  56. #define stricmp strcasecmp
  57. #endif
  58.  
  59. /*#define TRACE*/
  60. /*-------------------------- external data ----------------------------*/
  61. extern LINE *next_line,*curr_line;
  62. extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
  63. extern char current_screen;
  64. extern SCREEN_DETAILS screen[MAX_SCREENS];        /* screen structures */
  65. extern WINDOW *foot,*error_window;
  66. extern bool error_on_screen;
  67. extern char number_of_views;
  68. extern char number_of_files;
  69. extern char display_screens;                      /* number of screens */
  70. extern char *rec;
  71. extern unsigned short rec_len;
  72. extern char *cmd_rec;
  73. extern unsigned short cmd_rec_len;
  74. extern char in_profile;    /* indicates if processing profile */
  75. extern char mode_insert;        /* defines insert mode toggle */
  76. extern char file_disposition;
  77. extern struct stat stat_buf;
  78. extern char *temp_cmd;
  79. extern char dir_filename[10];
  80. extern char dir_pathname[MAX_FILE_NAME+1];
  81. #if !defined(NOREXX)
  82. extern char *rexxoutname;
  83. extern char rexx_filename[10];
  84. extern char rexx_pathname[MAX_FILE_NAME+1];
  85. #endif
  86. extern char sp_path[MAX_FILE_NAME+1] ;
  87. extern char sp_fname[MAX_FILE_NAME+1] ;
  88. extern char dir_path[MAX_FILE_NAME+1] ;    /* for dir and ls commands */
  89. /***********************************************************************/
  90. #ifdef PROTO
  91. short get_file(char *filename)
  92. #else
  93. short get_file(filename)
  94. char *filename;
  95. #endif
  96. /***********************************************************************/
  97. {
  98. /*-------------------------- external data ----------------------------*/
  99.  extern char CMD_LINEx;
  100.  extern char ERROR_ROWx;
  101.  extern char TAB_ROWx;
  102.  extern char TAB_ONx;
  103.  extern char SCALE_ROWx;
  104.  extern char SCALE_ONx;
  105.  extern char PREFIXx;
  106.  extern char CURRENT_ROW_POSx;
  107.  extern char STAYx;
  108.  extern char CASE_Ex;
  109.  extern char CASE_Lx;
  110.  extern char CASE_Cx;
  111.  extern char TABO_ONx;
  112.  extern char TABO_Nx;
  113.  extern char TABSx;
  114. /*--------------------------- local data ------------------------------*/
  115.  char fno;
  116.  LINE *curr;
  117.  char work_filename[MAX_FILE_NAME+1] ;
  118.  VIEW_DETAILS *save_current_view,*found_file;
  119.  int rc;
  120.  bool directory_file=FALSE;
  121. /*--------------------------- processing ------------------------------*/
  122. #ifdef TRACE
  123.  trace_function("file.c:    get_file");
  124. #endif
  125. /*---------------------------------------------------------------------*/
  126. /* Split the filename supplied into directory and filename parts.      */
  127. /* This is done before allocating a new current_file number.           */
  128. /*---------------------------------------------------------------------*/
  129.  
  130.  if ((rc = splitpath(filename)) != RC_OK)
  131.    {
  132.     display_error(10,filename);
  133. #ifdef TRACE
  134.     trace_return();
  135. #endif
  136.     return(rc);
  137.    }
  138. /*---------------------------------------------------------------------*/
  139. /* If the filename portion of the splithpath is empty, then we are     */
  140. /* editing a directory. So create the new file with the appropriate OS*/
  141. /* command and set the filename to DIR.DIR.                            */
  142. /*---------------------------------------------------------------------*/
  143.  if (strcmp(sp_fname,"") == 0)
  144.    {
  145.     if ((rc = read_directory()) != RC_OK)
  146.        {
  147. #ifdef TRACE
  148.         trace_return();
  149. #endif
  150.         return(rc);
  151.        }
  152.     strcpy(sp_path,dir_pathname);
  153.     strcpy(sp_fname,dir_filename);
  154.    }
  155. /*---------------------------------------------------------------------*/
  156. /* If this is the first file to be edited, don't check to see if the  */
  157. /* file is already in the ring. Obvious hey!                           */
  158. /*---------------------------------------------------------------------*/
  159.  if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)     /* no files in ring yet */
  160.    {
  161.     if ((rc = defaults_for_first_file()) != RC_OK)
  162.       {
  163. #ifdef TRACE
  164.        trace_return();
  165. #endif
  166.        return(rc);
  167.       }
  168.    }
  169.  else
  170.    {
  171. /*---------------------------------------------------------------------*/
  172. /* Here we should check if we already have the file to be edited in   */
  173. /* the ring. If the file is there and it is DIR.DIR, QQUIT out of it   */
  174. /* otherwise set the current pointer to it and exit.                   */
  175. /* Same applies to REXX output file.                                   */
  176. /*---------------------------------------------------------------------*/
  177.     save_current_view = CURRENT_VIEW;
  178.     if ((found_file = find_file(sp_path,sp_fname)) != (VIEW_DETAILS *)NULL)
  179.       {
  180.        CURRENT_VIEW = found_file;
  181. /*       if (CURRENT_FILE->pseudo_file == PSEUDO_DIR
  182.        ||  CURRENT_FILE->pseudo_file == PSEUDO_REXX)*/
  183. #if !defined(NOREXX)
  184.        if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
  185.        &&   strcmp(CURRENT_FILE->fpath,dir_pathname) == 0)
  186.        || (strcmp(CURRENT_FILE->fname,rexx_filename) == 0
  187.        &&  strcmp(CURRENT_FILE->fpath,rexx_pathname) == 0)) 
  188. #else
  189.        if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
  190.        &&   strcmp(CURRENT_FILE->fpath,dir_pathname) == 0))
  191. #endif
  192.          {
  193.           Qquit("");
  194.           if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)
  195.              rc = defaults_for_first_file();
  196.           else
  197.              rc = defaults_for_other_files();
  198.           if (rc != RC_OK)
  199.             {
  200. #ifdef TRACE
  201.              trace_return();
  202. #endif
  203.              return(rc);
  204.             }
  205.          }
  206.        else
  207.           {
  208. #ifdef TRACE
  209.            trace_return();
  210. #endif
  211.            return(RC_OK);
  212.           }
  213.       }
  214.     else
  215.       {
  216.        CURRENT_VIEW = save_current_view;
  217.        if ((rc = defaults_for_other_files()) != RC_OK)
  218.          {
  219. #ifdef TRACE
  220.           trace_return();
  221. #endif
  222.           return(rc);
  223.          }
  224.       }
  225.     }
  226. /*---------------------------------------------------------------------*/
  227. /* Increment the number of files in storage here, so that if there are */
  228. /* any problems with reading the file, free_file_memory() function can */
  229. /* correctly decrement the number of files.                            */
  230. /*---------------------------------------------------------------------*/
  231.  number_of_files++;
  232. /*---------------------------------------------------------------------*/
  233. /* Allocate memory to file pointer.                                    */
  234. /*---------------------------------------------------------------------*/
  235.  if ((CURRENT_FILE = (FILE_DETAILS *)malloc(sizeof(FILE_DETAILS))) == (FILE_DETAILS *)NULL)
  236.    {
  237.     free_view_memory();
  238.     display_error(30,(char *)"");
  239. #ifdef TRACE
  240.     trace_return();
  241. #endif
  242.     return(RC_OUT_OF_MEMORY);
  243.    }
  244. /*---------------------------------------------------------------------*/
  245. /* Set up default file attributes.                                     */
  246. /*---------------------------------------------------------------------*/
  247.  default_file_attributes();
  248.  if (strcmp(dir_filename,sp_fname) == 0)
  249.     CURRENT_FILE->pseudo_file = PSEUDO_DIR;
  250. #if !defined(NOREXX)
  251.  if (strcmp(rexxoutname,sp_fname) == 0)
  252.     CURRENT_FILE->pseudo_file = PSEUDO_REXX;
  253. #endif
  254. /*---------------------------------------------------------------------*/
  255. /* Copy the filename and path strings split up at the start of the     */
  256. /* function.                                                           */
  257. /*---------------------------------------------------------------------*/
  258.  if ((CURRENT_FILE->fname = (char *)malloc(strlen(sp_fname)+1)) == NULL)
  259.    {
  260.     free_view_memory();
  261.     display_error(30,(char *)"");
  262. #ifdef TRACE
  263.     trace_return();
  264. #endif
  265.     return(RC_OUT_OF_MEMORY);
  266.    }
  267.  if ((CURRENT_FILE->fpath = (char *)malloc(strlen(sp_path)+1)) == NULL)
  268.    {
  269.     free_view_memory();
  270.     display_error(30,(char *)"");
  271. #ifdef TRACE
  272.     trace_return();
  273. #endif
  274.     return(RC_OUT_OF_MEMORY);
  275.    }
  276.  strcpy(CURRENT_FILE->fname,sp_fname);
  277.  strcpy(CURRENT_FILE->fpath,sp_path);
  278.  
  279.  strcpy(work_filename,sp_path);
  280.  strcat(work_filename,sp_fname);
  281. /*---------------------------------------------------------------------*/
  282. /* If the file is not readable, then display error.                    */
  283. /*---------------------------------------------------------------------*/
  284.  if (!file_readable(work_filename))
  285.    {
  286.     display_error(8,work_filename);
  287.     free_view_memory();
  288. #ifdef TRACE
  289.     trace_return();
  290. #endif
  291.     return(RC_ACCESS_DENIED);
  292.    }
  293.  
  294.  if (file_exists(work_filename))
  295.    {
  296.     if (file_writable(work_filename))
  297.        file_disposition = FILE_NORMAL;
  298.     else
  299.       {
  300.        file_disposition = FILE_READONLY;
  301.        if (!in_profile)
  302.           display_error(0,(char *)"File is read-only...");
  303.       }
  304.     if ((CURRENT_FILE->fp = fopen(work_filename,"r")) == NULL)
  305.       {
  306. #ifdef TRACE
  307.        trace_return();
  308. #endif
  309.        return(RC_ACCESS_DENIED);
  310.       }
  311.    }
  312.  else
  313.    {
  314.     file_disposition = FILE_NEW;
  315.     if (!in_profile)
  316.        display_error(0,(char *)"New file...");
  317.    }
  318. /*---------------------------------------------------------------------*/
  319. /* first_line is set to "Top of File"                                  */
  320. /*---------------------------------------------------------------------*/
  321.  if ((CURRENT_FILE->first_line = add_line(CURRENT_FILE->first_line,NULL,TOP_OF_FILE,
  322.      strlen(TOP_OF_FILE))) == NULL)
  323.    {
  324.     free_view_memory();
  325. #ifdef TRACE
  326.     trace_return();
  327. #endif
  328.     return(RC_OUT_OF_MEMORY);
  329.    }
  330.  
  331.  curr = CURRENT_FILE->first_line;
  332. /*---------------------------------------------------------------------*/
  333. /* Read in the existing file...                                        */
  334. /*---------------------------------------------------------------------*/
  335.  CURRENT_FILE->number_lines = 0L;
  336.  if (file_disposition != FILE_NEW)
  337.    {
  338.     stat(work_filename,&stat_buf);
  339.     CURRENT_FILE->fmode = stat_buf.st_mode;
  340.     if ((curr = read_file(CURRENT_FILE->fp,curr,work_filename)) == NULL)
  341.       {
  342.        free_view_memory();
  343. #ifdef TRACE
  344.        trace_return();
  345. #endif
  346.        return(RC_ACCESS_DENIED);
  347.       }
  348.    }
  349.  else
  350.     CURRENT_FILE->fmode = FMODE;
  351. /*---------------------------------------------------------------------*/
  352. /* last line is set to "Bottom of File"                                */
  353. /*---------------------------------------------------------------------*/
  354.  if (add_line(CURRENT_FILE->first_line,curr,BOTTOM_OF_FILE,
  355.      strlen(BOTTOM_OF_FILE)) == NULL)
  356.    {
  357.     free_view_memory();
  358. #ifdef TRACE
  359.     trace_return();
  360. #endif
  361.     return(RC_OUT_OF_MEMORY);
  362.    }
  363.  
  364.  if (file_disposition != FILE_NEW)
  365.     fclose(CURRENT_FILE->fp);
  366.  
  367. #ifdef TRACE
  368.  trace_return();
  369. #endif
  370.  return(RC_OK);
  371. }
  372. /***********************************************************************/
  373. #ifdef PROTO
  374. LINE *read_file(FILE *fp,LINE *curr,char *filename)
  375. #else
  376. LINE *read_file(fp,curr,filename)
  377. FILE *fp;
  378. LINE *curr;
  379. char *filename;
  380. #endif
  381. /***********************************************************************/
  382. {
  383. /*-------------------------- external data ----------------------------*/
  384.  extern char TABI_ONx;
  385.  extern char TABI_Nx;
  386. /*--------------------------- local data ------------------------------*/
  387.  register unsigned short i;
  388.  short ch;
  389.  LINE *temp;
  390. /*--------------------------- processing ------------------------------*/
  391. #ifdef TRACE
  392.  trace_function("file.c:    read_file");
  393. #endif
  394.  temp = curr;
  395.  memset(rec,' ',max_line_length);
  396.  i = 0;
  397.  while(1)
  398.   {
  399.    ch = fgetc(fp);
  400.    if (feof(fp))
  401.      {
  402.       if (i > 0)     /* line with no CR and/or CR/LF */
  403.         {
  404.          if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
  405.            {
  406. #ifdef TRACE
  407.             trace_return();
  408. #endif
  409.             return(NULL);
  410.            }
  411.          CURRENT_FILE->number_lines++;
  412.         }
  413.       break;
  414.      }
  415.    if (ch == '\t'&& TABI_ONx)
  416.      {
  417.       do
  418.        {
  419.         rec[i] = ' ';
  420.         i++;
  421.         if (i >= max_line_length)
  422.           {
  423.            sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
  424.            display_error(29,rec);
  425. #ifdef TRACE
  426.            trace_return();
  427. #endif
  428.            return(NULL);
  429.           }
  430.        }
  431.       while ((i % TABI_Nx) != 0);
  432.       continue;
  433.      }
  434.    if (ch == '\n')
  435.      {
  436.       rec[i] = '\0';
  437.       if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
  438.         {
  439. #ifdef TRACE
  440.          trace_return();
  441. #endif
  442.          return(NULL);
  443.         }
  444.       CURRENT_FILE->number_lines++;
  445.       i = 0;
  446.       memset(rec,' ',max_line_length);
  447.       continue;
  448.      }
  449.    if (ch == '\r')
  450.      {
  451.       rec[i] = ch;
  452.       i++;
  453.       ch = fgetc(fp);
  454.       if (feof(fp))
  455.          break;
  456.       if (ch == '\n')
  457.         {
  458.          --i;
  459.          rec[i] = '\0';
  460.          if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
  461.            {
  462. #ifdef TRACE
  463.             trace_return();
  464. #endif
  465.             return(NULL);
  466.            }
  467.          CURRENT_FILE->number_lines++;
  468.          i = 0;
  469.          memset(rec,' ',max_line_length);
  470.          continue;
  471.         }
  472.      }
  473.    rec[i] = ch;
  474.    i++;
  475.    if (i >= max_line_length)
  476.      {
  477.       sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
  478.       display_error(29,rec);
  479. #ifdef TRACE
  480.       trace_return();
  481. #endif
  482.       return(NULL);
  483.      }
  484.   }
  485. #ifdef TRACE
  486.  trace_return();
  487. #endif
  488.  return(temp);
  489. }
  490. /***********************************************************************/
  491. #ifdef PROTO
  492. short save_file(FILE_DETAILS *cf,char *new_fname,char force,long in_lines,
  493.                 long start_line,char append,int start_col, int end_col)
  494. #else
  495. short save_file(cf,new_fname,force,in_lines,start_line,append,start_col,end_col)
  496. FILE_DETAILS *cf;
  497. char *new_fname;
  498. char force,append;
  499. long in_lines,start_line;
  500. int start_col,end_col;
  501. #endif
  502. /***********************************************************************/
  503. {
  504. /*--------------------------- local data ------------------------------*/
  505.  char *bak_filename=(char *)NULL;
  506.  char *write_fname=(char *)NULL;
  507.  register int i;
  508.  long j;
  509.  long num_lines=in_lines;
  510.  LINE *curr;
  511.  FILE *fp;
  512.  unsigned short col,newcol;
  513.  short off;
  514.  char c;
  515.  int rc;
  516.  bool same_file=TRUE;
  517.  int anerror;
  518. /*--------------------------- processing ------------------------------*/
  519. #ifdef TRACE
  520.  trace_function("file.c:    save_file");
  521. #endif
  522.  if ((write_fname = (char *)malloc(MAX_FILE_NAME)) == NULL)
  523.    {
  524.     display_error(30,(char *)"");
  525. #ifdef TRACE
  526.     trace_return();
  527. #endif
  528.     return(RC_OUT_OF_MEMORY);
  529.    }
  530. /*---------------------------------------------------------------------*/
  531. /* If a new filename is specified, use it as the old filename.         */
  532. /*---------------------------------------------------------------------*/
  533.  (void *)strtrans(new_fname,OSLASH,ISLASH);
  534.  if (strcmp(new_fname,"") != 0)                  /* new_fname supplied */
  535.    {
  536. /*---------------------------------------------------------------------*/
  537. /* Split the supplied new filename.                                    */
  538. /*---------------------------------------------------------------------*/
  539.     if ((rc = splitpath(new_fname)) != RC_OK)
  540.       {
  541.        display_error(10,new_fname);
  542.        if (bak_filename != (char *)NULL)
  543.           free(bak_filename);
  544.        if (write_fname != (char *)NULL)
  545.           free(write_fname);
  546. #ifdef TRACE
  547.        trace_return();
  548. #endif
  549.        return(rc);
  550.       }
  551.     strcpy(write_fname,sp_path);
  552.     strcat(write_fname,sp_fname);
  553.     same_file = FALSE;
  554. /*---------------------------------------------------------------------*/
  555. /* Test to make sure that the write fname doesn't exist...             */
  556. /* ...unless we are forcing the write.                                 */
  557. /*---------------------------------------------------------------------*/
  558.     if ((!force) && file_exists(write_fname))
  559.       {
  560.        display_error(31,write_fname);
  561.        if (bak_filename != (char *)NULL)
  562.           free(bak_filename);
  563.        if (write_fname != (char *)NULL)
  564.           free(write_fname);
  565. #ifdef TRACE
  566.        trace_return();
  567. #endif
  568.        return(RC_ACCESS_DENIED);
  569.       }
  570. /*---------------------------------------------------------------------*/
  571. /* Test to make sure that we can write the file.                       */
  572. /*---------------------------------------------------------------------*/
  573.     if (!file_writable(write_fname))
  574.       {
  575.        display_error(8,write_fname);
  576.        if (bak_filename != (char *)NULL)
  577.           free(bak_filename);
  578.        if (write_fname != (char *)NULL)
  579.           free(write_fname);
  580. #ifdef TRACE
  581.        trace_return();
  582. #endif
  583.        return(RC_ACCESS_DENIED);
  584.       }
  585.    }
  586.  else
  587.    {
  588. /*---------------------------------------------------------------------*/
  589. /* We are using the same file name for the new file.                   */
  590. /* Create the name of the current file.                                */
  591. /*---------------------------------------------------------------------*/
  592.     strcpy(write_fname,cf->fpath);
  593.     strcat(write_fname,cf->fname);
  594. /*---------------------------------------------------------------------*/
  595. /* If the file exists, test to make sure we can write it and save a    */
  596. /* backup copy.                                                        */
  597. /*---------------------------------------------------------------------*/
  598.     if (file_exists(write_fname))
  599.       {
  600. /*---------------------------------------------------------------------*/
  601. /* Test to make sure that we can write the file.                       */
  602. /*---------------------------------------------------------------------*/
  603.        if (!file_writable(write_fname))
  604.          {
  605.           display_error(8,write_fname);
  606.           if (bak_filename != (char *)NULL)
  607.              free(bak_filename);
  608.           if (write_fname != (char *)NULL)
  609.              free(write_fname);
  610. #ifdef TRACE
  611.           trace_return();
  612. #endif
  613.           return(RC_ACCESS_DENIED);
  614.          }
  615. /*---------------------------------------------------------------------*/
  616. /* Rename the current file to filename.bak.                            */
  617. /*---------------------------------------------------------------------*/
  618.        if ((bak_filename =
  619.            (char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  620.          {
  621.           display_error(30,(char *)"");
  622.           if (bak_filename != (char *)NULL)
  623.              free(bak_filename);
  624.           if (write_fname != (char *)NULL)
  625.              free(write_fname);
  626. #ifdef TRACE
  627.           trace_return();
  628. #endif
  629.           return(RC_OUT_OF_MEMORY);
  630.          }
  631.        new_filename(cf->fpath,cf->fname,bak_filename,(char *)".bak");
  632.        if (cf->fp != NULL)
  633.          {
  634.           remove_file(bak_filename);
  635.           if (rename(write_fname,bak_filename) != 0)
  636.             {
  637.              display_error(8,write_fname);
  638.              if (bak_filename != (char *)NULL)
  639.                 free(bak_filename);
  640.              if (write_fname != (char *)NULL)
  641.                 free(write_fname);
  642. #ifdef TRACE
  643.              trace_return();
  644. #endif
  645.              return(RC_ACCESS_DENIED);
  646.             }
  647.          }
  648.       }
  649.    }
  650. /*---------------------------------------------------------------------*/
  651. /* Open the file we are writing to...                                  */
  652. /*---------------------------------------------------------------------*/
  653.  if (append == YES)
  654.     fp = fopen(write_fname,"ab");
  655.  else
  656.     fp = fopen(write_fname,"wb");
  657.  if (fp == NULL)
  658.    {
  659.     display_error(8,(char *)"could not open for writing");
  660.     if (bak_filename != (char *)NULL)
  661.        free(bak_filename);
  662.     if (write_fname != (char *)NULL)
  663.        free(write_fname);
  664. #ifdef TRACE
  665.     trace_return();
  666. #endif
  667.     return(RC_ACCESS_DENIED);
  668.    }
  669. /*---------------------------------------------------------------------*/
  670. /* Determine where to start writing from in the linked list.           */
  671. /* If the number of lines is greater than zero, then only that many    */
  672. /* lines are written to the output file.                               */
  673. /* When the number of lines is equal to zero, write out the whole file.*/
  674. /*---------------------------------------------------------------------*/
  675.  if (num_lines > 0L)   /* called from put(d) command */
  676. #ifdef USE_VOID
  677.     curr = (LINE *)ll_find((LINE *)cf->first_line,start_line);
  678. #else
  679.     curr = lll_find(cf->first_line,start_line);
  680. #endif
  681.  else
  682.    {
  683.     curr = cf->first_line;
  684.     num_lines = cf->number_lines + 1; /* forces following for to work */
  685.    }
  686. /*---------------------------------------------------------------------*/
  687. /* Now write out the contents of the file array to the new filename.   */
  688. /*---------------------------------------------------------------------*/
  689.  rc = RC_OK;
  690.  for (j=0L;j<num_lines && curr->next != NULL;j++)
  691.    {
  692.     if (curr->prev != NULL)  /* not first line */
  693.       {
  694.        if (cf->tabsout_on)
  695.          {
  696.           col = 0;
  697.           off = start_col;
  698.           while (1)
  699.             {
  700.              newcol = col;
  701.              while ((c = next_char(curr,&off,end_col+1)) == ' ')
  702.                {
  703.                 newcol++;
  704.                 if ((newcol % cf->tabsout_num) == 0)
  705.                   {
  706.                    if ((rc = write_char((char)'\t',fp)) == RC_DISK_FULL)
  707.                       break;
  708.                    col = newcol;
  709.                   }
  710.                }
  711.              for (;col<newcol;col++)
  712.                  if ((rc = write_char((char)' ',fp)) == RC_DISK_FULL)
  713.                     break;
  714.              if (off == (-1))  /* end of line */
  715.                 break;
  716.              if ((rc = write_char((char)c,fp)) == RC_DISK_FULL)
  717.                 break;
  718.              col++;
  719.             }
  720.           if (rc) break;
  721.          }
  722.        else
  723.          {
  724.           for (i=start_col;i<min(curr->length,end_col+1);i++)
  725.               if ((rc = write_char((char)*(curr->line+i),fp)) == RC_DISK_FULL)
  726.                  break;
  727.          }
  728.        if (rc) break;
  729. /*       col = 0;*/
  730.        if (cf->eolout == EOLOUT_CRLF)
  731.          {
  732.           if ((rc = write_char((char)'\r',fp)) == RC_DISK_FULL)
  733.              break;
  734.          }
  735.        if ((rc = write_char((char)'\n',fp)) == RC_DISK_FULL)
  736.           break;
  737.       }
  738.     if (rc) break;
  739.     curr = curr->next;
  740.    }
  741.  anerror = errno;
  742.  if (fflush(fp) == EOF)
  743.    {
  744.     rc = RC_DISK_FULL;
  745.     clearerr(fp);
  746.    }
  747.  if (fclose(fp) == EOF)
  748.     rc = RC_DISK_FULL;
  749.  if (rc)
  750.     clearerr(fp);
  751. /*---------------------------------------------------------------------*/
  752. /* If an error occurred in writing the file (usuallly a result of a    */
  753. /* disk full error), get the files back to the way they were before    */
  754. /* this attempt to write them.                                         */
  755. /*---------------------------------------------------------------------*/
  756.  if (rc)
  757.    {
  758.     /* remove 'new' file (the one that couldn't be written) */
  759.     remove_file(write_fname);
  760.     if (same_file)
  761.       {
  762.        if (rename(bak_filename,write_fname) != 0)
  763.          {
  764.           display_error(8,write_fname);
  765.           if (bak_filename != (char *)NULL)
  766.              free(bak_filename);
  767.           if (write_fname != (char *)NULL)
  768.              free(write_fname);
  769. #ifdef TRACE
  770.           trace_return();
  771. #endif
  772.           return(RC_ACCESS_DENIED);
  773.          }
  774.       }
  775.    }
  776.  else
  777.    {
  778.     if (cf->fmode != 0)
  779.        chmod(write_fname,cf->fmode);
  780. /*---------------------------------------------------------------------*/
  781. /* If a backup file is not to be kept, remove the backup file provided */
  782. /* that there hasn't been a problem in writing the file.               */
  783. /*---------------------------------------------------------------------*/
  784.     if (!cf->backup)
  785.        remove_file(bak_filename);
  786. /*---------------------------------------------------------------------*/
  787. /* If a new filename was not supplied, free up temporary memory.       */
  788. /*---------------------------------------------------------------------*/
  789.    }
  790.  if (bak_filename != (char *)NULL)
  791.     free(bak_filename);
  792.  if (write_fname != (char *)NULL)
  793.     free(write_fname);
  794.  
  795. #ifdef TRACE
  796.  trace_return();
  797. #endif
  798.  return(rc);
  799. }
  800. /***********************************************************************/
  801. #ifdef PROTO
  802. int write_char(char chr,FILE *fp)
  803. #else
  804. int write_char(chr,fp)
  805. char chr;
  806. FILE *fp;
  807. #endif
  808. /***********************************************************************/
  809. {
  810. /*--------------------------- local data ------------------------------*/
  811. /*--------------------------- processing ------------------------------*/
  812.  if (fputc(chr,fp) == chr
  813.  && ferror(fp) == 0)
  814.     return(RC_OK);
  815.  clearerr(fp);
  816.  display_error(57,(char *)"");
  817.  return(RC_DISK_FULL);
  818. }
  819. /***********************************************************************/
  820. #ifdef PROTO
  821. int increment_alt(FILE_DETAILS *cf)
  822. #else
  823. int increment_alt(cf)
  824. FILE_DETAILS *cf;
  825. #endif
  826. /***********************************************************************/
  827. {
  828. /*--------------------------- local data ------------------------------*/
  829.  register short i;
  830.  char *aus_filename;
  831. /*--------------------------- processing ------------------------------*/
  832. #ifdef TRACE
  833.  trace_function("file.c:    increment_alt");
  834. #endif
  835.  cf->autosave_alt++;
  836.  cf->save_alt++;
  837. /*---------------------------------------------------------------------*/
  838. /* We can now test for autosave_alt exceeding the defined limit and    */
  839. /* carry out an autosave if necessary.                                 */
  840. /*---------------------------------------------------------------------*/
  841.  if (cf->autosave != 0
  842.  && cf->autosave_alt >= cf->autosave)
  843.    {
  844.     if ((aus_filename =
  845.        (char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  846.       {
  847.        display_error(30,(char *)"");
  848. #ifdef TRACE
  849.        trace_return();
  850. #endif
  851.        return(RC_OUT_OF_MEMORY);
  852.       }
  853.     new_filename(cf->fpath,cf->fname,aus_filename,(char *)".aus");
  854.     save_file(cf,aus_filename,YES,0L,0L,NO,0,max_line_length);
  855.     free(aus_filename);
  856.     cf->autosave_alt = 0;
  857.    }
  858. #ifdef TRACE
  859.  trace_return();
  860. #endif
  861.  return(RC_OK);
  862. }
  863. /***********************************************************************/
  864. #ifdef PROTO
  865. char *new_filename(char *ofp,char *ofn,
  866.                             char *nfn,char *ext)
  867. #else
  868. char *new_filename(ofp,ofn,nfn,ext)
  869. char *ofp,*ofn,*nfn,*ext;
  870. #endif
  871. /***********************************************************************/
  872. {
  873. /*--------------------------- local data ------------------------------*/
  874.  short rc;
  875. /*--------------------------- processing ------------------------------*/
  876. #ifdef TRACE
  877.  trace_function("file.c:    new_filename");
  878. #endif
  879.  strcpy(nfn,ofp);
  880.  strcat(nfn,ofn);
  881. #ifdef DOS
  882.  rc = strzeq(nfn,'.');
  883.  if (rc != (-1))
  884.     *(nfn+rc) = '\0';
  885. #endif
  886. #ifdef OS2
  887.  if (!LongFileNames(nfn)) /* returns TRUE if HPFS filesystem */
  888.    {
  889.     rc = strzreveq(nfn,'.');
  890.     if (rc != (-1))
  891.        *(nfn+rc) = '\0';
  892.    }
  893. #endif
  894.  strcat(nfn,ext);
  895. #ifdef TRACE
  896.  trace_return();
  897. #endif
  898.  return(nfn);
  899. }
  900. /***********************************************************************/
  901. #ifdef PROTO
  902. int remove_aus_file(FILE_DETAILS *cf)
  903. #else
  904. int remove_aus_file(cf)
  905. FILE_DETAILS *cf;
  906. #endif
  907. /***********************************************************************/
  908. {
  909. /*--------------------------- local data ------------------------------*/
  910.  register short i;
  911.  char *aus_filename;
  912. /*--------------------------- processing ------------------------------*/
  913. #ifdef TRACE
  914.  trace_function("file.c:    remove_aus_file");
  915. #endif
  916.  if ((aus_filename =
  917.     (char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  918.    {
  919.     display_error(30,(char *)"");
  920. #ifdef TRACE
  921.     trace_return();
  922. #endif
  923.     return(RC_OUT_OF_MEMORY);
  924.    }
  925.  new_filename(cf->fpath,cf->fname,aus_filename,(char *)".aus");
  926.  remove_file(aus_filename);
  927.  free(aus_filename);
  928. #ifdef TRACE
  929.  trace_return();
  930. #endif
  931.  return(RC_OK);
  932. }
  933. /***********************************************************************/
  934. #ifdef PROTO
  935. int free_view_memory(void)
  936. #else
  937. int free_view_memory()
  938. #endif
  939. /***********************************************************************/
  940. {
  941. /*--------------------------- local data ------------------------------*/
  942.  char save_current_screen;
  943.  short original_number_of_files=number_of_files;
  944.  int rc;
  945. /*--------------------------- processing ------------------------------*/
  946. #ifdef TRACE
  947.  trace_function("file.c:    free_view_memory");
  948. #endif
  949.  if (--CURRENT_FILE->file_views == 0)
  950.     free_file_memory();
  951.  free_a_view();
  952.  
  953. /*---------------------------------------------------------------------*/
  954. /* The following procedures are only carried out when the number of    */
  955. /* screens is > 1.                                                     */
  956. /*---------------------------------------------------------------------*/
  957.  if (display_screens > 1)
  958.    {
  959. /*---------------------------------------------------------------------*/
  960. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  961. /* | a | b |     | a | a |         or       | a | b |  c  | a | a |    */
  962. /* |   |   | --> |   |   |                  |   |   |     |   |   |    */
  963. /* |   |qq |     |   |   |                  |   |qq |     |   |   |    */
  964. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  965. /* number_of_files > 1                                                 */
  966. /*---------------------------------------------------------------------*/
  967.     if (original_number_of_files > 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
  968.        if (CURRENT_SCREEN.screen_view->file_for_view !=
  969.            OTHER_SCREEN.screen_view->file_for_view)
  970.          {
  971.           if ((rc = defaults_for_other_files()) != RC_OK)
  972.             {
  973. #ifdef TRACE
  974.              trace_return();
  975. #endif
  976.              return(rc);
  977.             }
  978.           CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
  979.           CURRENT_FILE->file_views++;
  980.           if ((rc = set_up_windows()) != RC_OK)
  981.             {
  982. #ifdef TRACE
  983.              trace_return();
  984. #endif
  985.              return(rc);
  986.             }
  987.           CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  988. /*        repaint_screen(); */
  989.          }
  990.        else
  991. /*---------------------------------------------------------------------*/
  992. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  993. /* | a | a |  b  | b | b |         or       | a | a | b c | b | b |    */
  994. /* |   |   | --> |   |   |                  |   |   |     |   |   |    */
  995. /* |   |qq |     |   |   |                  |   |qq |     |   |   |    */
  996. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  997. /* number_of_files > 1                                                 */
  998. /*---------------------------------------------------------------------*/
  999.          {
  1000.           free_file_memory();
  1001.           free_a_view();
  1002.           if ((rc = defaults_for_other_files()) != RC_OK)
  1003.             {
  1004. #ifdef TRACE
  1005.              trace_return();
  1006. #endif
  1007.              return(rc);
  1008.             }
  1009.           if ((rc = set_up_windows()) != RC_OK)
  1010.             {
  1011. #ifdef TRACE
  1012.              trace_return();
  1013. #endif
  1014.              return(rc);
  1015.             }
  1016.           OTHER_SCREEN.screen_view = CURRENT_VIEW;
  1017.           CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
  1018.           repaint_screen();
  1019.           if ((rc = set_up_windows()) != RC_OK)
  1020.             {
  1021. #ifdef TRACE
  1022.              trace_return();
  1023. #endif
  1024.              return(rc);
  1025.             }
  1026.           CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  1027.           CURRENT_FILE->file_views++;
  1028.          }
  1029. /*---------------------------------------------------------------------*/
  1030. /* +---+---+                                                           */
  1031. /* | a | a |                                                           */
  1032. /* |   |   | --> exit                                                  */
  1033. /* |qq |   |                                                           */
  1034. /* +---+---+                                                           */
  1035. /* number_of_files = 1                                                 */
  1036. /*---------------------------------------------------------------------*/
  1037.     if (original_number_of_files == 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
  1038.        if (CURRENT_SCREEN.screen_view->file_for_view ==
  1039.            OTHER_SCREEN.screen_view->file_for_view)
  1040.          {
  1041.           CURRENT_FILE->file_views--;
  1042.           free_file_memory();
  1043.           free_a_view();
  1044.          }
  1045.    }
  1046.  
  1047.  if (number_of_views > 0
  1048.  && !in_profile)
  1049.    {
  1050.     pre_process_line(CURRENT_VIEW->focus_line);
  1051.     show_page();
  1052.     if (CURRENT_VIEW->prefix)
  1053.        touchwin(CURRENT_WINDOW_PREFIX);
  1054.     touchwin(CURRENT_WINDOW_COMMAND);
  1055.     touchwin(CURRENT_WINDOW_IDLINE);
  1056.     touchwin(CURRENT_WINDOW_MAIN);
  1057.     touchwin(CURRENT_WINDOW);
  1058.     show_heading();
  1059.    }
  1060. #ifdef TRACE
  1061.  trace_return();
  1062. #endif
  1063.  return(RC_OK);
  1064. }
  1065. /***********************************************************************/
  1066. #ifdef PROTO
  1067. void free_a_view(void)
  1068. #else
  1069. void free_a_view()
  1070. #endif
  1071. /***********************************************************************/
  1072. {
  1073. /*--------------------------- local data ------------------------------*/
  1074. /*--------------------------- processing ------------------------------*/
  1075. #ifdef TRACE
  1076.  trace_function("file.c:    free_a_view");
  1077. #endif
  1078. /*---------------------------------------------------------------------*/
  1079. /* If the marked block is within the current view, unset the variables.*/
  1080. /*---------------------------------------------------------------------*/
  1081.  if (MARK_VIEW == CURRENT_VIEW)
  1082.     MARK_VIEW = (VIEW_DETAILS *)NULL;
  1083. /*---------------------------------------------------------------------*/
  1084. /* Delete the windows associated with the current view.                */
  1085. /* Only do this if we are running interactively.                       */
  1086. /*---------------------------------------------------------------------*/
  1087.  if (!in_profile && CURRENT_WINDOW_MAIN != (WINDOW *)NULL)
  1088.    {
  1089.     if (CURRENT_VIEW->prefix)
  1090.        delwin(CURRENT_WINDOW_PREFIX);
  1091.     delwin(CURRENT_WINDOW_MAIN);
  1092.     delwin(CURRENT_WINDOW_COMMAND);
  1093.     delwin(CURRENT_WINDOW_ARROW);
  1094.     delwin(CURRENT_WINDOW_IDLINE);
  1095.    }
  1096. #ifdef USE_VOID
  1097.  if ((CURRENT_VIEW = (VIEW_DETAILS *)ll_del((void *)vd_first,(void *)CURRENT_VIEW,DIRECTION_FORWARD)) == (VIEW_DETAILS *)NULL)
  1098. #else
  1099.  CURRENT_VIEW = vll_del(&vd_first,NULL,CURRENT_VIEW,DIRECTION_FORWARD);
  1100. #endif
  1101.  
  1102.  number_of_views--;
  1103.  return;
  1104. }
  1105. /***********************************************************************/
  1106. #ifdef PROTO
  1107. int free_file_memory(void)
  1108. #else
  1109. int free_file_memory()
  1110. #endif
  1111. /***********************************************************************/
  1112. {
  1113. /*--------------------------- local data ------------------------------*/
  1114.  LINE *curr;
  1115.  register int i;
  1116. /*--------------------------- processing ------------------------------*/
  1117. #ifdef TRACE
  1118.  trace_function("file.c:    free_file_memory");
  1119. #endif
  1120.  if (CURRENT_FILE->fname != NULL)
  1121.    {
  1122.     free(CURRENT_FILE->fname);
  1123.     CURRENT_FILE->fname = (char *)NULL;
  1124.    }
  1125.  if (CURRENT_FILE->fpath != NULL)
  1126.    {
  1127.     free(CURRENT_FILE->fpath);
  1128.     CURRENT_FILE->fpath = (char *)NULL;
  1129.    }
  1130. #ifdef USE_VOID
  1131.  ll_free((void *)CURRENT_FILE->first_line);
  1132. #else
  1133.  CURRENT_FILE->first_line = lll_free(CURRENT_FILE->first_line);
  1134. #endif
  1135.  if (CURRENT_FILE != NULL)
  1136.    {
  1137.     free(CURRENT_FILE);
  1138.     CURRENT_FILE = (FILE_DETAILS *)NULL;
  1139.    }
  1140.  
  1141.  number_of_files--;
  1142.  
  1143. #ifdef TRACE
  1144.  trace_return();
  1145. #endif
  1146.  return(RC_OK);
  1147. }
  1148. /***********************************************************************/
  1149. #ifdef PROTO
  1150. int read_directory(void)
  1151. #else
  1152. int read_directory()
  1153. #endif
  1154. /***********************************************************************/
  1155. {
  1156. /*--------------------------- local data ------------------------------*/
  1157.  struct dirfile *dpfirst=NULL,*dplast=NULL,*dp;
  1158.  char str_attr[11];
  1159.  char str_date[10];
  1160.  char str_time[6];
  1161. #ifdef UNIX
  1162.  struct tm *timp;
  1163. #endif
  1164.  int rc;
  1165.  FILE *fp;
  1166. /*--------------------------- processing ------------------------------*/
  1167. #ifdef TRACE
  1168.  trace_function("file.c:    read_directory");
  1169. #endif
  1170. /*---------------------------------------------------------------------*/
  1171. /* Get all file info for the selected files into structure. If no file */
  1172. /* name specified, force it to '*'.                                    */
  1173. /*---------------------------------------------------------------------*/
  1174.  if (strcmp(sp_fname,"") == 0)
  1175.     rc = getfiles(sp_path,(char *)"*",&dpfirst,&dplast);
  1176.  else
  1177.     rc = getfiles(sp_path,sp_fname,&dpfirst,&dplast);
  1178.  if (rc != RC_OK)
  1179.    {
  1180.     display_error(rc,sp_path);
  1181. #ifdef TRACE
  1182.     trace_return();
  1183. #endif
  1184.     return(RC_FILE_NOT_FOUND);
  1185.    }
  1186.  if (dpfirst == dplast)
  1187.    {
  1188.     display_error(9,sp_path);
  1189. #ifdef TRACE
  1190.     trace_return();
  1191. #endif
  1192.     return(RC_FILE_NOT_FOUND);
  1193.    }
  1194. /*---------------------------------------------------------------------*/
  1195. /* dir_path is set up here so that subsequent sos_edit commands can use*/
  1196. /* the directory path as a prefix to the edit files filename.          */
  1197. /*---------------------------------------------------------------------*/
  1198.  strcpy(dir_path,sp_path);
  1199. /*---------------------------------------------------------------------*/
  1200. /* sort the array of file structures.                                  */
  1201. /*---------------------------------------------------------------------*/
  1202.  qsort(dpfirst,dplast - dpfirst,sizeof(struct dirfile),fcomp);
  1203. /*---------------------------------------------------------------------*/
  1204. /* open the DIR.DIR file for output, overwriting any previous data     */
  1205. /*---------------------------------------------------------------------*/
  1206.  strcpy(temp_cmd,dir_pathname);
  1207.  strcat(temp_cmd,dir_filename);
  1208.  if ((fp = fopen(temp_cmd,"w")) == NULL)
  1209.    {
  1210.     display_error(8,sp_path);
  1211. #ifdef TRACE
  1212.     trace_return();
  1213. #endif
  1214.     return(RC_ACCESS_DENIED);
  1215.    }
  1216. /*---------------------------------------------------------------------*/
  1217. /* write out the formatted contents of the file structures.            */
  1218. /*---------------------------------------------------------------------*/
  1219.  for (dp=dpfirst;dp<dplast;dp++)
  1220.     {
  1221. #ifdef UNIX
  1222.      timp = localtime(&(dp->ftime));
  1223. #endif
  1224.      fprintf(fp,"%s ",file_attrs(dp->fattr,str_attr));
  1225.      fprintf(fp,"%8ld ",dp->fsize);
  1226.      fprintf(fp,"%s ",file_date(D_NAME,str_date));
  1227.      fprintf(fp,"%s ",file_time(T_NAME,str_time));
  1228.      fprintf(fp,"%s\n",dp->fname);
  1229.      free(dp->fname);
  1230.     }
  1231.  free(dpfirst);
  1232.  fclose(fp);
  1233.  
  1234. #ifdef TRACE
  1235.  trace_return();
  1236. #endif
  1237.  return(RC_OK);
  1238. }
  1239. /***********************************************************************/
  1240. #ifdef PROTO
  1241. VIEW_DETAILS *find_file(char *fp,char *fn)
  1242. #else
  1243. VIEW_DETAILS *find_file(fp,fn)
  1244. char *fp,*fn;
  1245. #endif
  1246. /***********************************************************************/
  1247. {
  1248. /*--------------------------- local data ------------------------------*/
  1249.  VIEW_DETAILS *save_current_view,*found_file;
  1250. /*--------------------------- processing ------------------------------*/
  1251. #ifdef TRACE
  1252.  trace_function("file.c:    find_file");
  1253. #endif
  1254.  save_current_view = CURRENT_VIEW;
  1255.  CURRENT_VIEW = vd_first;
  1256.  while(CURRENT_VIEW != (VIEW_DETAILS *)NULL)
  1257.    {
  1258. #ifdef UNIX
  1259.     if (strcmp(CURRENT_FILE->fname,fn) == 0
  1260.     &&  strcmp(CURRENT_FILE->fpath,fp) == 0)
  1261. #else
  1262.     if (stricmp(CURRENT_FILE->fname,fn) == 0
  1263.     &&  stricmp(CURRENT_FILE->fpath,fp) == 0)
  1264. #endif
  1265.       {
  1266. #ifdef TRACE
  1267.        trace_return();
  1268. #endif
  1269.        found_file = CURRENT_VIEW;
  1270.        CURRENT_VIEW = save_current_view;
  1271.        return(found_file);
  1272.       }
  1273.     CURRENT_VIEW = CURRENT_VIEW->next;
  1274.    }
  1275. #ifdef TRACE
  1276.  trace_return();
  1277. #endif
  1278.  CURRENT_VIEW = save_current_view;
  1279.  return((VIEW_DETAILS *)NULL);
  1280. }
  1281. /***********************************************************************/
  1282. #ifdef PROTO
  1283. int execute_command_file(FILE *fp)
  1284. #else
  1285. int execute_command_file(fp)
  1286. FILE *fp;
  1287. #endif
  1288. /***********************************************************************/
  1289. {
  1290. /*--------------------------- local data ------------------------------*/
  1291.  register int i;
  1292.  char ch;
  1293.  int rc=RC_OK;
  1294.  char profile_command_line[MAX_COMMAND_LENGTH];
  1295. /*--------------------------- processing ------------------------------*/
  1296. #ifdef TRACE
  1297.  trace_function("file.c:    execute_command_file");
  1298. #endif
  1299.  
  1300.  memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
  1301.  i = 0;
  1302.  while(1)
  1303.   {
  1304.    ch = fgetc(fp);
  1305.    if (feof(fp))
  1306.       break;
  1307.    if (ch == '\n')
  1308.      {
  1309.       profile_command_line[i] = '\0';
  1310.       rc = process_command_line(profile_command_line);
  1311.       if (number_of_files == 0)
  1312.          break;
  1313.       i = 0;
  1314.       memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
  1315.       continue;
  1316.      }
  1317.    if (ch == '\r')
  1318.      {
  1319.       profile_command_line[i] = ch;
  1320.       i++;
  1321.       ch = fgetc(fp);
  1322.       if (feof(fp))
  1323.          break;
  1324.       if (ch == '\n')
  1325.         {
  1326.          --i;
  1327.          profile_command_line[i] = '\0';
  1328.          rc = process_command_line(profile_command_line);
  1329.          if (number_of_files == 0)
  1330.             break;
  1331.          i = 0;
  1332.          memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
  1333.          continue;
  1334.         }
  1335.      }
  1336.    profile_command_line[i] = ch;
  1337.    i++;
  1338.   }
  1339. #ifdef TRACE
  1340.  trace_return();
  1341. #endif
  1342.  return(rc);
  1343. }
  1344. /***********************************************************************/
  1345. #ifdef PROTO
  1346. int process_command_line(char *profile_command_line)
  1347. #else
  1348. int process_command_line(profile_command_line)
  1349. char *profile_command_line;
  1350. #endif
  1351. /***********************************************************************/
  1352. {
  1353. /*--------------------------- local data ------------------------------*/
  1354.  int rc=RC_OK;
  1355.  int len;
  1356.  bool strip=FALSE;
  1357. /*--------------------------- processing ------------------------------*/
  1358. #ifdef TRACE
  1359.  trace_function("file.c:    process_command_line");
  1360. #endif
  1361. /*---------------------------------------------------------------------*/
  1362. /* If the line begins with a comment, just return.                     */
  1363. /*---------------------------------------------------------------------*/
  1364.  if (memcmp(profile_command_line,"/*",2) == 0)    /* is a comment line */
  1365.    {
  1366. #ifdef TRACE
  1367.     trace_return();
  1368. #endif
  1369.     return(rc);
  1370.    }
  1371. /*---------------------------------------------------------------------*/
  1372. /* If the line begins and ends with a quote, single or double, strip   */
  1373. /* the quotes.                                                         */
  1374. /*---------------------------------------------------------------------*/
  1375.  len = strlen(profile_command_line);
  1376.  if (*(profile_command_line) == '\''
  1377.  &&  *(profile_command_line+len-1) == '\'')
  1378.     strip = TRUE;
  1379.  if (*(profile_command_line) == '"'
  1380.  &&  *(profile_command_line+len-1) == '"')
  1381.     strip = TRUE;
  1382.  if (strip)
  1383.    {
  1384.     *(profile_command_line+len-1) = '\0';
  1385.     profile_command_line++;
  1386.    }
  1387.  rc = command_line(profile_command_line,COMMAND_ONLY_FALSE);
  1388.  
  1389. #ifdef TRACE
  1390.  trace_return();
  1391. #endif
  1392.  return(rc);
  1393. }
  1394.