home *** CD-ROM | disk | FTP | other *** search
- /*=============================================================================
-
- The INSTALL program source code, object code, sample script files,
- executable program, and documentation are subject to copyright
- protection under the laws of the United States and other countries.
-
- This software is licensed, not sold, and may only be redistributed
- in executable format and only in accordance with the provisions of
- the INSTALL Source Code License Agreement.
-
- INSTALL is Copyright(C) 1987-1990 by Knowledge Dynamics Corp
- Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
- 512-964-3994 (Voice) 512-964-3958 (24-hr FAX)
-
- All rights reserved worldwide.
-
- ===============================================================================
-
- FILENAME:
- s_openou.c
-
- AUTHOR:
- eric jon heflin
-
- PUBLIC FUNCTIONS:
- smart_open_out() - open a new file with multi-level path
-
- LOCAL FUNCTIONS:
- mkpath() - create a multi-level subdirectory
-
- DESCRIPTION:
- smart_open_out() opens a new file specified. If it returns to its caller,
- it was successful. It will create multiple new subdirectories if
- necessary. If the output file was partially written, then this function
- opens the file in append mode, but will not create the file (since it
- should already exist).
-
- REVISION HISTORY:
- DATE: AUTHOR: DESCRIPTION OF CHANGES:
- 891211 allyn jordan documentation
- 900102 ejh cosmetic changes
- 900115 ejh Added PC Lint compatibility.
-
- ==============================================================================*/
-
- #include <ctype.h>
- #include "install.h"
- #include <string.h>
- #if defined(__MICROSOFTC__)
- #include <io.h>
- #include <direct.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #elif defined(__TURBOC__)
- #include <io.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #elif defined(LATTICE)
- #include <types.h>
- #include <stat.h>
- #endif
-
- #include <fcntl.h>
-
- static void mkpath(project_t *, byte, byte *);
-
- disk_t dummy = {NULL, NULL, NULL};
-
- int smart_open_out(project, file)
- project_t *project;
- file_t *file;
- {
- int out = -1;
- byte out_file[150];
- byte path[100], dr[5];
- byte *s;
- word type = 0;
-
- /* prompt the end-user for a new output disk if disk is removable */
- if (project->removable)
- new_out_disk(project, &dummy, file);
-
- if (!file->abs)
- sprintf(out_file, "%c:%s%s", project->out_drive, project->subdir, file->out_fname);
- else
- strcpy(out_file, file->out_fname);
- if (file->expand)
- {
- /* expanded files are always written to temp.$$$ */
- byte pa[100], dr2[3];
- parse_file(out_file, dr2, pa, NULL, NULL);
- sprintf(out_file, "%c:%sTEMP.$$$", dr2[0], pa);
- if (file->bytes_written == 0l)
- {
- /* remove any existing output file */
- if (exists(out_file))
- remove(out_file);
- }
- }
- if (file->bytes_written != 0L || (file->append == TRUE && !file->expand))
- {
- /*
- * File has already been written to, just open for appending.
- */
- if (!exists(out_file))
- error("Unable to reopen output file: \"%s\"", out_file);
- if((out = open(out_file, O_WRONLY | O_APPEND | O_BINARY, S_IWRITE)) == -1)
- error("Unable to reopen output file: \"%s\"", out_file);
- smart_seek(out, 0L, SEEK_END, out_file);
- if (file->append)
- {
- sputs(" Appending: ");
- sputs(out_file);
- sputs("\n");
- }
- return out;
- }
- else
- {
- /*
- * File does not exist, create.
- */
- out = -1;
- if (exists(out_file))
- remove(out_file);
- /*
- if (exists(out_file))
- {
- if(file->overwrite == ASKOVERWRITE)
- {
- wputs(yes_w, "The file \"%s\" already exists and is about",out_file);
- wputs(yes_w, "to be overwritten.");
- wputs(yes_w, NULL);
- wputs(yes_,w "Overwrite (Y/N)?");
- if(!put_yes(yes_w))
- {
- file->damaged = TRUE; * force skip *
- return -1;
- }
- remove(out_file);
- }
- }
- */
- while ((out = open(out_file, O_WRONLY | O_BINARY | O_CREAT, S_IWRITE)) == -1)
- {
- out = -1; /* ensure out is flagged as invalid */
- s = dosprob(&type);
- if (type & USER)
- {
- wputs(retry_w, "Unable to open file: %s", out_file);
- wputs(retry_w, s);
- put_retry(retry_w);
- }
- else
- break; /* assume subdir did not exist */
- }
- if (out != -1)
- return out;
- }
-
- /*------------------------------------------------------------------------
- *
- * This code, which is executed if initial attempt to open output
- * file failed, attempts to make a directory.
- *
- *-----------------------------------------------------------------------*/
-
- /* strsfn separates a fully specified file name into its components */
- parse_file(out_file, dr, path, NULL, NULL);
-
- if (path[0] == '\0') /* path was root, abort */
- error("Unable to open output file: \"%s\"", out_file);
-
- /* if mkpath returns, it was successful */
- mkpath(project, dr[0], path);
-
- while ((out = open(out_file, O_WRONLY | O_BINARY | O_CREAT, S_IWRITE)) == -1)
- {
- wputs(retry_w, dosprob(&type));
- wputs(retry_w, "Unable to open output file: %s", out_file);
- put_retry(retry_w);
- }
-
- /* we were successful, return file handle */
- return out;
- } /* smart_open_out */
-
-
- /*
- * Create a directory. Supports creation of multiple sub-directories.
- * This function exits to DOS if the path could not be created, thus
- * a return to its caller indicates success.
- */
-
- static void mkpath(project_t * project, byte drive, byte *path)
- { /* mkpath */
- int nx[16];
- byte temp[200];
- int i, j, len;
-
- if (drive > 26)
- drive = (byte)(toupper(drive) - 'A');
- /* first change to proper drive, if we are not already there */
- if (getdisk() != drive)
- setdisk(drive);
- i = getdisk();
- if (i != drive)
- {
- wputs(error_w, dosprob(NULL));
- wputs(error_w, "Unable to change to drive: %c:", drive + 'A');
- put_error(error_w);
- }
-
- strcpy(temp, path); /* create local copy */
- /* parse file path */
- len = (int)strlen(temp);
- if (temp[len - 1] == '\\')
- temp[len - 1] = '\0';
- for (i = 0, j = 0; temp[i] != '\0'; ++i)
- {
- if (temp[i] == '\\')
- {
- temp[i] = '\0';
- nx[j++] = i + 1;
- }
- }
- nx[j] = -1;
-
- chdir("\\"); /* start from the root dir */
- for (i = 0; nx[i] != -1; ++i)
- {
- /* attempt to change to succeedingly lower subdirs */
- if (chdir(&temp[nx[i]]) != -1)
- continue;
-
- /* change failed, try to make new dir */
- if(!project->terse)
- {
- sputs(" Making: ");
- sputs(&temp[nx[i]]);
- sputs("\n");
- }
- if (mkdir(&temp[nx[i]]) == -1)
- error("Unable to make new directory: \"%s\"", &temp[nx[i]]);
-
- if (chdir(&temp[nx[i]]) == -1)
- error("Unable to change to new directory: \"%s\"", &temp[nx[i]]);
- }
-
- /* if we get to this point, the path has been successfully created */
- } /* mkpath */
-
-
- /* end-of-file */
-
-