Ultrix-3.1/src/cmd/ltf/initvol.c
/**********************************************************************
* 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 **\\**\\**\\**\\**\\*/