/********************************************************************** * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. * * All Rights Reserved. * * Reference "/usr/src/COPYRIGHT" for applicable restrictions. * **********************************************************************/ #ifndef lint static char *sccsid = "@(#)initvol.c 3.0 (ULTRIX) 4/21/86"; #endif lint /**/ /* * * File name: * * initvol.c * * Source file description: * * This file contains the functions pertaining to * the initialization of a new volume for output. * * Functions: * * initvol() Top-level logic for volume creation. * * tree() Changes current working directory * (if required) and calls putfile to * place a file on the output volume. * * Usage: * * n/a * * Compile: * * cc -O -c initvol.c <- For Ultrix-32/32m * * cc CFLAGS=-DU11-O initvol.c <- For Ultrix-11 * * * Modification History: * ~~~~~~~~~~~~~~~~~~~~ * * revision comments * -------- ----------------------------------------------- * 01.0 30-Apr-85 Ray Glaser * Create original version * * 01.1 19-SEP-85 Suzanne Logcher * Add logic to check the validity of all file * names, either on-line arguments, stdin, or * a file of file names. If on-line arguments, * removes unknown files and prints warning * message. If stdin, checks after input, and * rejects unknown file. If by file, checks for * unknown files, and if any exist, asks user to * either abort or skip over unknown files. */ /* * +--> Local Includes */ #include "ltfdefs.h" /* Common Global Defs % structs */ /**/ /* * * Function: * * initvol * * Function Description: * * This function is the top-level entry routine for the * creation of an entirely new output volume. ie. Any and * all data previously recorded on the volume is lost. * It is entered from the main() function of module "ltf.c". * * Arguments: * * int num Number of arguments to process * char *args[] Array of pointers to arguments * int iflag -I option flag (if arguments are being * being passed from an input file) * char *inputfile Name of the possible input file of args. * * * Return values: * * none * * Side Effects: * * This function never returns to the caller. Good or bad, * an exit is always taken to the system. */ initvol(num, args, iflag, inputfile) int num; /* number of arguments to process */ char *args[]; /* array of pointers to arguments */ int iflag; /* -I option */ char *inputfile; { /* * +--> Local Variables */ char dummy[MAXPATHLEN+1]; int dumpflag = 0; struct FILESTAT *fstat; FILE *ifp; char line[512]; /* line from passwd file */ int ll = FALSE; char oowner[15]; /* orignal owner name string */ int ret; int ret1; int ret2; int stnum; char *temp; struct stat tinode; struct stat tinodes; int tnum; int ttnum; int uid; /* uid of user */ /*------*\ Code \*------*/ /* Check file list for nonexistent files and print warning * then bump file name off list */ if (num > 0) { stnum = num; for (tnum = stnum, i = 0; tnum > 0; tnum--, i++) { ret1 = lstat(args[i], &tinode); ret2 = stat(args[i], &tinodes); if (ret1 < 0 || ret2 < 0) { if ((tinode.st_mode & S_IFMT) == S_IFLNK && ret2 < 0) PERROR "%s: %s %s%c\n", Progname, CANTSTS, args[i], BELL); else PERROR "%s: %s %s%c\n", Progname, CANTSTW, args[i], BELL); perror(Progname); printf("\n"); stnum--; tnum--; for (ttnum = tnum, j = i; ttnum > 0; ttnum--, j++) { temp = args[j]; args[j] = args[j+1]; args[j+1] = temp; } tnum++; i--; } }/* tnum > 0 */ if (stnum == 0) { PERROR "\n%s: %s %c\n", Progname, NOVALFI, BELL); exit(FAIL); } for (tnum = 0; tnum < stnum; tnum++) rec_args(args[tnum], dumpflag); }/* num > 0 */ /* Check for non-existent files named in input file. If found, * ask user if they want to quit (to edit input file) or to just * skip the unknown file upon creation */ if (iflag == 1) { if ((ifp = fopen(inputfile, "r")) == NULL) { PERROR "\n%s: %s %s%c\n\n", Progname, CANTOPEN, inputfile, BELL); perror(Progname); exit(FAIL); } stnum = 0; while ((ret = rec_file(ifp, iflag, dummy)) != EOF) { if (ret) { ret1 = lstat(dummy, &tinode); ret2 = stat(dummy, &tinodes); if (ret1 < 0 || ret2 < 0) { if ((tinode.st_mode & S_IFMT) == S_IFLNK && ret2 < 0) PERROR "%s: %s %s%c\n", Progname, CANTSTS, dummy, BELL); else PERROR "%s: %s %s%c\n", Progname, CANTSTW, dummy, BELL); perror(Progname); PROMPT "%s: %s ", Progname, STOPCRIN); gets(Labelbuf); if (Labelbuf[0] == 'y') exit(FAIL); else skip = TRUE; printf("\n"); } else { rec_args(dummy, dumpflag); stnum++; } }/*T ret */ }/*E while ret ..*/ if (stnum == 0) { PERROR "\n%s: %s %c\n", Progname, NOVALFI, BELL); exit(FAIL); } fclose(ifp); }/*T iflag == 1 */ /* Check for non-existent files as they are inputted by the stdin. * If file is unknown, reject it, and ask for another. All valid * file names are stored on a linked list, fstat. */ if (iflag == -1) { stnum = 0; while ((ret = rec_file(stdin, iflag, dummy)) != EOF) { if (ret) { ret1 = lstat(dummy, &tinode); ret2 = stat(dummy, &tinodes); if (ret1 < 0 || ret2 < 0) { if ((tinode.st_mode & S_IFMT) == S_IFLNK && ret2 < 0) PERROR "%s: %s %s%c\n", Progname, CANTSTS, dummy, BELL); else PERROR "%s: %s %s%c\n", Progname, CANTSTW, dummy, BELL); perror(Progname); } else { rec_args(dummy, dumpflag); stnum++; } } } if (stnum == 0) { PERROR "\n%s: %s %c\n", Progname, NOVALFI, BELL); exit(FAIL); } printf("\n"); } /**/ /* Try to open device. If error, print message and exit */ if (!(Magtfp = fopen(Magtdev, "w"))) { PERROR "\n%s: %s %s%c\n", Progname, CANTOPEN, Magtdev, BELL); perror(Progname); exit(FAIL); } /* * As the default owner identification of this volume, get * the user's name from the /etc/passwd file based on * the current real uid .. */ uid = getuid(); if (getpw(uid,line)) { PERROR "\n%s: %s %d%c\n", Progname, CANTFPW, uid, BELL); strcpy(line, " "); } /* * Owner id field in VOL1 label is maximum of 14 chtrs (38-51) */ for (j=0; j < 14 && line[j] && line[j] != ':'; j++) Owner[j] = line[j]; /* * Ensure owner id field is truncated to 14 (or less) chctrs. */ Owner[j] = 0; /* * Ultrix permits non-"A"-character login names. * Save a copy of the orginal version for error message * reporting and check to see if this is the case. */ strcpy(oowner,Owner); if (!(filter_to_a(Owner,REPORT_ERRORS))) { PERROR "\n%s: %s %s %c", Progname, INVOWN, oowner, BELL); PERROR "\n%s: %s %s\n\n", Progname, INVVID2, Owner); exit(FAIL); } #ifdef U11 ret = ghostname(Hostname, 21); #else ret = gethostname(Hostname, 21); #endif if (ret) { PERROR "\n%s: %s\n", Progname, HOSTF); perror(Progname); exit(FAIL); } /******\ Output Volume Label --> VOL1 \******/ /* * This area will require an "update" when we add VERSION 4 logic ! */ sprintf(Labelbuf, "VOL1%-6.6s %-13.13s%-13.13s%-14.14s%28.28s%c", Volid, Spaces, (Ansiv == '4') ? IMPID : Spaces, Owner, Spaces, Ansiv); if ((write(fileno(Magtfp), Labelbuf, BUFSIZE)) <= 0) { PERROR "\n%s: %s %s%c\n\n", Progname, CANTWVL, Magtdev, BELL); perror(Magtdev); ceot(); } Fsecno = Fseqno = 1; /**/ /* * If arguments on F_head list, process */ if (F_head) { for (; stnum; stnum--) { /* Get names off fstat from the end first */ fstat = F_head; if (stnum > 1) for (i = 1; i < stnum; i++, fstat = fstat->f_next) ; /* * Reset global default/user designated file * type for output. */ Dfiletype = 0; /* * Go change directories (if required) and * put the file onto the output volume. */ tree(fstat->f_src, iflag); }/*E for (; stnum; stnum--) */ }/*T if (F_head) */ else { PERROR "\n%s: %s %c\n", Progname, NOVALFI, BELL); exit(FAIL); } /* * Write final tape mark to signify end of all data * on this volume. * ie. A double set of tape marks should indicate EOV .. * */ weof(); printf("\n"); exit(SUCCEED); }/*E initvol() */ /**/ /* * * Function: * * tree * * Function Description: * * This function changes the current working directory * (if required) before calling the "putfile" logic to * place the designated file on the output volume. * Working directory is changed back to the orginal * on completion of the "putfile". * * Arguments: * * char *pathname Pointer to the pathname (file) * to be written to the output vol. * * Return values: * * none * * Side Effects: * * If the routine cannot successfully change directories, * a message is output to "stderr" and the function * exits to system control. * */ tree(pathname, iflag) char *pathname; int iflag; { /* * +--> Local Variables */ char wdir[MAXPATHLEN]; /* Save working directory */ int ret = TRUE; /* Check if putfile good */ /*------*\ Code \*------*/ if (! getwd(wdir)) { PERROR "\n%s: %s %s%c\n\n", Progname, GETWDF, wdir, BELL); perror(Progname); exit(FAIL); } cp2 = pathname; if (strcmp(pathname, "/")) { for (cp = pathname; *cp; cp++) if (*cp == '/') cp2 = cp; if (cp2 != pathname) cp2++; } /* * Go put file(s) onto the output volume. */ ret = putfile(!strcmp(pathname, "/") ? "" : pathname, cp2, iflag, wdir); if (chdir(wdir) < 0) { PERROR "\n%s: %s %s%c\n\n", Progname, CANTCHD, wdir, BELL); perror(Progname); exit(FAIL); } if (ret = EOF) return(EOF); return(TRUE); }/*E tree() */ /**\\**\\**\\**\\**\\** EOM initvol.c **\\**\\**\\**\\**\\*/ /**\\**\\**\\**\\**\\** EOM initvol.c **\\**\\**\\**\\**\\*/