home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0020 - 0029 / ibm0020-0029 / ibm0028.tar / ibm0028 / INSTALL2.TD0 / SOURCES.LIF / S_OPENOU.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-27  |  6.8 KB  |  256 lines

  1. /*=============================================================================
  2.  
  3.      The INSTALL program source code, object code, sample  script files,
  4.      executable  program,  and  documentation  are  subject to copyright
  5.      protection under the laws of the United States and other countries.
  6.  
  7.      This software is licensed, not sold, and may only be  redistributed
  8.      in  executable format and only in accordance with the provisions of
  9.      the INSTALL Source Code License Agreement.
  10.  
  11.         INSTALL is Copyright(C) 1987-1990 by Knowledge Dynamics Corp
  12.        Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
  13.               512-964-3994 (Voice)   512-964-3958 (24-hr FAX)
  14.  
  15.                       All rights reserved worldwide.
  16.  
  17. ===============================================================================
  18.  
  19. FILENAME:
  20.     s_openou.c
  21.  
  22. AUTHOR:
  23.     eric jon heflin
  24.  
  25. PUBLIC FUNCTIONS:
  26.     smart_open_out() - open a new file with multi-level path
  27.  
  28. LOCAL FUNCTIONS:
  29.     mkpath()         - create a multi-level subdirectory
  30.  
  31. DESCRIPTION:
  32.      smart_open_out() opens a new file specified.  If it returns to its caller,
  33.     it was successful.  It will create multiple new subdirectories if 
  34.     necessary.  If the output file was partially written, then this function 
  35.     opens the file in append mode, but will not create the file (since it 
  36.     should already exist).
  37.  
  38. REVISION HISTORY:
  39.     DATE:    AUTHOR:            DESCRIPTION OF CHANGES:
  40.     891211    allyn jordan    documentation
  41.     900102    ejh                cosmetic changes
  42.     900115    ejh                Added PC Lint compatibility.
  43.  
  44. ==============================================================================*/
  45.  
  46. #include <ctype.h>
  47. #include "install.h"
  48. #include <string.h>
  49. #if defined(__MICROSOFTC__)
  50. #include <io.h>
  51. #include <direct.h>
  52. #include <sys\types.h>
  53. #include <sys\stat.h>
  54. #elif defined(__TURBOC__)
  55. #include <io.h>
  56. #include <sys\types.h>
  57. #include <sys\stat.h>
  58. #elif defined(LATTICE)
  59. #include <types.h>
  60. #include <stat.h>
  61. #endif
  62.  
  63. #include <fcntl.h>
  64.  
  65. static void mkpath(project_t *, byte, byte *);
  66.  
  67. disk_t dummy = {NULL, NULL, NULL};
  68.  
  69. int smart_open_out(project, file)
  70. project_t *project;
  71. file_t *file;
  72.     {
  73.     int out = -1;
  74.     byte out_file[150];
  75.     byte path[100], dr[5];
  76.     byte *s;
  77.     word type = 0;
  78.  
  79.     /* prompt the end-user for a new output disk if disk is removable */
  80.     if (project->removable)
  81.         new_out_disk(project, &dummy, file);
  82.  
  83.     if (!file->abs)
  84.         sprintf(out_file, "%c:%s%s", project->out_drive, project->subdir, file->out_fname);
  85.     else
  86.         strcpy(out_file, file->out_fname);
  87.     if (file->expand)
  88.         {
  89.         /* expanded files are always written to temp.$$$ */
  90.         byte pa[100], dr2[3];
  91.         parse_file(out_file, dr2, pa, NULL, NULL);
  92.         sprintf(out_file, "%c:%sTEMP.$$$", dr2[0], pa);
  93.         if (file->bytes_written == 0l)
  94.             {
  95.             /* remove any existing output file */
  96.             if (exists(out_file))
  97.                 remove(out_file);
  98.             }
  99.         }
  100.     if (file->bytes_written != 0L || (file->append == TRUE && !file->expand))
  101.         {
  102.         /*
  103.          *    File has already been written to, just open for appending.
  104.          */
  105.         if (!exists(out_file))
  106.             error("Unable to reopen output file: \"%s\"", out_file);
  107.         if((out = open(out_file, O_WRONLY | O_APPEND | O_BINARY, S_IWRITE)) == -1)
  108.             error("Unable to reopen output file: \"%s\"", out_file);
  109.         smart_seek(out, 0L, SEEK_END, out_file);
  110.         if (file->append)
  111.             {
  112.             sputs("     Appending: ");
  113.             sputs(out_file);
  114.             sputs("\n");
  115.             }
  116.         return out;
  117.         }
  118.     else
  119.         {
  120.         /*
  121.          *    File does not exist, create.
  122.          */
  123.         out = -1;
  124.         if (exists(out_file))
  125.             remove(out_file);
  126. /*
  127.         if (exists(out_file))
  128.             {
  129.             if(file->overwrite == ASKOVERWRITE)
  130.                 {
  131.                 wputs(yes_w, "The file \"%s\" already exists and is about",out_file);
  132.                 wputs(yes_w, "to be overwritten.");
  133.                 wputs(yes_w, NULL);
  134.                 wputs(yes_,w "Overwrite (Y/N)?");
  135.                 if(!put_yes(yes_w))
  136.                     {
  137.                     file->damaged = TRUE;    * force skip *
  138.                     return -1;
  139.                     }
  140.                     remove(out_file);
  141.                 }
  142.             }
  143.         */
  144.         while ((out = open(out_file, O_WRONLY | O_BINARY | O_CREAT, S_IWRITE)) == -1)
  145.             {
  146.             out = -1;   /* ensure out is flagged as invalid */
  147.             s = dosprob(&type);
  148.             if (type & USER)
  149.                 {
  150.                 wputs(retry_w, "Unable to open file: %s", out_file);
  151.                 wputs(retry_w, s);
  152.                 put_retry(retry_w);
  153.                 }
  154.             else
  155.                 break;    /* assume subdir did not exist */
  156.             }
  157.         if (out != -1)
  158.             return out;
  159.         }
  160.  
  161.     /*------------------------------------------------------------------------
  162.      *
  163.      *    This code, which is executed if initial attempt to open output
  164.      *    file failed, attempts to make a directory.
  165.      *
  166.      *-----------------------------------------------------------------------*/
  167.  
  168.     /* strsfn separates a fully specified file name into its components */
  169.     parse_file(out_file, dr, path, NULL, NULL);
  170.  
  171.     if (path[0] == '\0')    /* path was root, abort */
  172.         error("Unable to open output file: \"%s\"", out_file);
  173.  
  174.     /* if mkpath returns, it was successful */
  175.     mkpath(project, dr[0], path);
  176.  
  177.     while ((out = open(out_file, O_WRONLY | O_BINARY | O_CREAT, S_IWRITE)) == -1)
  178.         {
  179.         wputs(retry_w, dosprob(&type));
  180.         wputs(retry_w, "Unable to open output file: %s", out_file);
  181.         put_retry(retry_w);
  182.         }
  183.  
  184.     /* we were successful, return file handle */
  185.     return out;
  186.     }                    /* smart_open_out */
  187.  
  188.  
  189. /*
  190.  *    Create a directory.  Supports creation of multiple sub-directories.
  191.  *    This function exits to DOS if the path could not be created, thus
  192.  *    a return to its caller indicates success.
  193.  */
  194.  
  195. static void mkpath(project_t * project, byte drive, byte *path)
  196.     {                    /* mkpath */
  197.     int nx[16];
  198.     byte temp[200];
  199.     int i, j, len;
  200.  
  201.     if (drive > 26)
  202.         drive = (byte)(toupper(drive) - 'A');
  203.     /* first change to proper drive, if we are not already there */
  204.     if (getdisk() != drive)
  205.         setdisk(drive);
  206.     i = getdisk();
  207.     if (i != drive)
  208.         {
  209.         wputs(error_w, dosprob(NULL));
  210.         wputs(error_w, "Unable to change to drive: %c:", drive + 'A');
  211.         put_error(error_w);
  212.         }
  213.  
  214.     strcpy(temp, path);    /* create local copy */
  215.     /* parse file path */
  216.     len = (int)strlen(temp);
  217.     if (temp[len - 1] == '\\')
  218.         temp[len - 1] = '\0';
  219.     for (i = 0,  j = 0;  temp[i] != '\0';  ++i)
  220.         {
  221.         if (temp[i] == '\\')
  222.             {
  223.             temp[i] = '\0';
  224.             nx[j++] = i + 1;
  225.             }
  226.         }
  227.     nx[j] = -1;
  228.  
  229.     chdir("\\");        /* start from the root dir */
  230.     for (i = 0;  nx[i] != -1;  ++i)
  231.         {
  232.         /* attempt to change to succeedingly lower subdirs */
  233.         if (chdir(&temp[nx[i]]) != -1)
  234.             continue;
  235.  
  236.         /* change failed, try to make new dir */
  237.         if(!project->terse)
  238.             {
  239.             sputs("        Making: ");
  240.             sputs(&temp[nx[i]]);
  241.             sputs("\n");
  242.             }
  243.         if (mkdir(&temp[nx[i]]) == -1)
  244.             error("Unable to make new directory: \"%s\"", &temp[nx[i]]);
  245.  
  246.         if (chdir(&temp[nx[i]]) == -1)
  247.             error("Unable to change to new directory: \"%s\"", &temp[nx[i]]);
  248.         }
  249.  
  250.     /* if we get to this point, the path has been successfully created */
  251.     }                    /* mkpath    */
  252.  
  253.  
  254. /* end-of-file */
  255.  
  256.