⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* $Source: /u/mark/src/pax/RCS/fileio.c,v $ * * $Revision: 1.2 $ * * fileio.c - file I/O functions for all archive interfaces * * DESCRIPTION * *	These function all do I/O of some form or another.  They are *	grouped here mainly for convienence. * * AUTHOR * *	Mark H. Colburn, NAPS International (mark@jhereg.mn.org) * * Sponsored by The USENIX Association for public distribution.  * * Copyright (c) 1989 Mark H. Colburn. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice is duplicated in all such  * forms and that any documentation, advertising materials, and other  * materials related to such distribution and use acknowledge that the  * software was developed * by Mark H. Colburn and sponsored by The  * USENIX Association.  * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * $Log:	fileio.c,v $ * Revision 1.2  89/02/12  10:04:31  mark * 1.2 release fixes *  * Revision 1.1  88/12/23  18:02:09  mark * Initial revision *  */#ifndef lintstatic char *ident = "$Id: fileio.c,v 1.2 89/02/12 10:04:31 mark Exp $";static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";#endif /* ! lint *//* Headers */#include "pax.h"/* open_archive -  open an archive file.   * * DESCRIPTION * *	Open_archive will open an archive file for reading or writing, *	setting the proper file mode, depending on the "mode" passed to *	it.  All buffer pointers are reset according to the mode *	specified. * * PARAMETERS * * 	int	mode 	- specifies whether we are reading or writing.    * * RETURNS * *	Returns a zero if successfull, or -1 if an error occured during  *	the open. */#ifdef __STDC__    int open_archive(int mode)#else    int open_archive(mode)int             mode;#endif{    if (ar_file[0] == '-' && ar_file[1] == '\0') {	if (mode == AR_READ) {	    archivefd = STDIN;	    bufend = bufidx = bufstart;	} else {	    archivefd = STDOUT;	}    } else if (mode == AR_READ) {	archivefd = open(ar_file, O_RDONLY | O_BINARY);	bufend = bufidx = bufstart;	/* set up for initial read */    } else if (mode == AR_WRITE) {	archivefd = open(ar_file, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0666);    } else if (mode == AR_APPEND) {	archivefd = open(ar_file, O_RDWR | O_BINARY, 0666);	bufend = bufidx = bufstart;	/* set up for initial read */    }    if (archivefd < 0) {	warnarch(strerror(), (OFFSET) 0);	return (-1);    }    ++arvolume;    return (0);}/* close_archive - close the archive file * * DESCRIPTION * *	Closes the current archive and resets the archive end of file *	marker. */#ifdef __STDC__void close_archive(void)#else    void close_archive()#endif{    if (archivefd != STDIN && archivefd != STDOUT) {	close(archivefd);    }    areof = 0;}/* openout - open an output file * * DESCRIPTION * *	Openo opens the named file for output.  The file mode and type are *	set based on the values stored in the stat structure for the file. *	If the file is a special file, then no data will be written, the *	file/directory/Fifo, etc., will just be created.  Appropriate *	permission may be required to create special files. * * PARAMETERS * *	char 	*name		- The name of the file to create *	Stat	*asb		- Stat structure for the file *	Link	*linkp;		- pointer to link chain for this file *	int	 ispass		- true if we are operating in "pass" mode * * RETURNS * * 	Returns the output file descriptor, 0 if no data is required or -1  *	if unsuccessful. Note that UNIX open() will never return 0 because  *	the standard input is in use.  */#ifdef __STDC__int openout(char *name, Stat *asb, Link *linkp, int ispass)#else    int openout(name, asb, linkp, ispass)char           *name;Stat           *asb;Link           *linkp;int             ispass;#endif{    int             exists;    int             fd;    ushort          perm;    ushort          operm = 0;    Stat            osb;#ifdef	S_IFLNK    int             ssize;    char            sname[PATH_MAX + 1];#endif	/* S_IFLNK */    if (exists = (LSTAT(name, &osb) == 0)) {	if (ispass && osb.sb_ino == asb->sb_ino && osb.sb_dev == asb->sb_dev) {	    warn(name, "Same file");	    return (-1);	} else if ((osb.sb_mode & S_IFMT) == (asb->sb_mode & S_IFMT)) {	    operm = osb.sb_mode & S_IPERM;	} else if (REMOVE(name, &osb) < 0) {	    warn(name, strerror());	    return (-1);	} else {	    exists = 0;	}    }    if (linkp) {	if (exists) {	    if (asb->sb_ino == osb.sb_ino && asb->sb_dev == osb.sb_dev) {		return (0);	    } else if (unlink(name) < 0) {		warn(name, strerror());		return (-1);	    } else {		exists = 0;	    }	}	if (link(linkp->l_name, name) != 0) {	    if (errno == ENOENT) {		if (f_dir_create) {		    if (dirneed(name) != 0 ||			    link(linkp->l_name, name) != 0) {			    warn(name, strerror());			return (-1);		    }		} else {		    warn(name, 			     "Directories are not being created (-d option)");		}		return(0);	    } else if (errno != EXDEV) {		warn(name, strerror());		return (-1);	    }	} else {	    return(0);	}     }    perm = asb->sb_mode & S_IPERM;    switch (asb->sb_mode & S_IFMT) {    case S_IFBLK:    case S_IFCHR:#ifdef _POSIX_SOURCE	warn(name, "Can't create special files");	return (-1);#else	fd = 0;	if (exists) {	    if (asb->sb_rdev == osb.sb_rdev) {		if (perm != operm && chmod(name, (int) perm) < 0) {		    warn(name, strerror());		    return (-1);		} else {		    break;		}	    } else if (REMOVE(name, &osb) < 0) {		warn(name, strerror());		return (-1);	    } else {		exists = 0;	    }	}	if (mknod(name, (int) asb->sb_mode, (int) asb->sb_rdev) < 0) {	    if (errno == ENOENT) {		if (f_dir_create) {		    if (dirneed(name) < 0 || mknod(name, (int) asb->sb_mode, 			   (int) asb->sb_rdev) < 0) {			warn(name, strerror());			return (-1);		    }		} else {		    warn(name, "Directories are not being created (-d option)");		}	    } else {		warn(name, strerror());		return (-1);	    }	}	return(0);#endif /* _POSIX_SOURCE */	break;    case S_IFDIR:	if (exists) {	    if (perm != operm && chmod(name, (int) perm) < 0) {		warn(name, strerror());		return (-1);	    }	} else if (f_dir_create) {	    if (dirmake(name, asb) < 0 || dirneed(name) < 0) {		warn(name, strerror());		return (-1);	    }	} else {	    warn(name, "Directories are not being created (-d option)");	}	return (0);#ifndef _POSIX_SOURCE#ifdef	S_IFIFO    case S_IFIFO:	fd = 0;	if (exists) {	    if (perm != operm && chmod(name, (int) perm) < 0) {		warn(name, strerror());		return (-1);	    }	} else if (mknod(name, (int) asb->sb_mode, 0) < 0) {	    if (errno == ENOENT) {		if (f_dir_create) {		    if (dirneed(name) < 0		       || mknod(name, (int) asb->sb_mode, 0) < 0) {			warn(name, strerror());			return (-1);		    }		} else {		    warn(name, "Directories are not being created (-d option)");		}	    } else {		warn(name, strerror());		return (-1);	    }	}	return(0);	break;#endif				/* S_IFIFO */#endif				/* _POSIX_SOURCE */#ifdef	S_IFLNK    case S_IFLNK:	if (exists) {	    if ((ssize = readlink(name, sname, sizeof(sname))) < 0) {		warn(name, strerror());		return (-1);	    } else if (strncmp(sname, asb->sb_link, ssize) == 0) {		return (0);	    } else if (REMOVE(name, &osb) < 0) {		warn(name, strerror());		return (-1);	    } else {		exists = 0;	    }	}	if (symlink(asb->sb_link, name) < 0) {	    if (errno == ENOENT) {		if (f_dir_create) {		    if (dirneed(name) < 0 || symlink(asb->sb_link, name) < 0) {			warn(name, strerror());			return (-1);		    }		} else {		    warn(name, "Directories are not being created (-d option)");		}	    } else {		warn(name, strerror());		return (-1);	    }	}	return (0);		/* Can't chown()/chmod() a symbolic link */#endif				/* S_IFLNK */    case S_IFREG:	if (exists) {	    if (!f_unconditional && osb.sb_mtime > asb->sb_mtime) {		warn(name, "Newer file exists");		return (-1);	    } else if (unlink(name) < 0) {		warn(name, strerror());		return (-1);	    } else {		exists = 0;	    }	}	if ((fd = creat(name, (int) perm)) < 0) {	    if (errno == ENOENT) {		if (f_dir_create) {		    if (dirneed(name) < 0 || 			    (fd = creat(name, (int) perm)) < 0) {			warn(name, strerror());			return (-1);		    }		} else {		    /* 		     * the file requires a directory which does not exist		     * and which the user does not want created, so skip		     * the file...		     */		    warn(name, "Directories are not being created (-d option)");		    return(0);		}	    } else {		warn(name, strerror());		return (-1);	    }	}	break;    default:	warn(name, "Unknown filetype");	return (-1);    }    if (f_owner) {	if (!exists || asb->sb_uid != osb.sb_uid || asb->sb_gid != osb.sb_gid) {	    chown(name, (int) asb->sb_uid, (int) asb->sb_gid);	}    }    return (fd);}/* openin - open the next input file * * DESCRIPTION * *	Openi will attempt to open the next file for input.  If the file is *	a special file, such as a directory, FIFO, link, character- or *	block-special file, then the file size field of the stat structure *	is zeroed to make sure that no data is written out for the file. *	If the file is a special file, then a file descriptor of 0 is *	returned to the caller, which is handled specially.  If the file *	is a regular file, then the file is opened and a file descriptor *	to the open file is returned to the caller. * * PARAMETERS * *	char   *name	- pointer to the name of the file to open *	Stat   *asb	- pointer to the stat block for the file to open * * RETURNS * * 	Returns a file descriptor, 0 if no data exists, or -1 at EOF. This  *	kludge works because standard input is in use, preventing open() from  *	returning zero.  */#ifdef __STDC__int openin(char *name, Stat *asb)#else    int openin(name, asb)char           *name;		/* name of file to open */Stat           *asb;		/* pointer to stat structure for file */#endif{    int             fd;    switch (asb->sb_mode & S_IFMT) {    case S_IFDIR:	asb->sb_nlink = 1;	asb->sb_size = 0;	return (0);#ifdef	S_IFLNK    case S_IFLNK:	if ((asb->sb_size = readlink(name,			     asb->sb_link, sizeof(asb->sb_link) - 1)) < 0) {	    warn(name, strerror());	    return(0);	}	asb->sb_link[asb->sb_size] = '\0';	return (0);#endif				/* S_IFLNK */    case S_IFREG:	if (asb->sb_size == 0) {	    return (0);	}	if ((fd = open(name, O_RDONLY | O_BINARY)) < 0) {	    warn(name, strerror());	}	return (fd);    default:	asb->sb_size = 0;	return (0);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -