示例#1
0
文件: ex_io.c 项目: n-t-roff/ex-3.6
/*
 * Write a file.
 */
void
wop(bool dofname)
/* bool dofname;	/ * if 1 call filename, else use savedfile */
{
	register int c, exclam, nonexist;
	line *saddr1, *saddr2;
	struct stat stbuf;

	c = 0;
	exclam = 0;
	if (dofname) {
		if (peekchar() == '!')
			exclam++, ignchar();
		ignore(skipwh());
		while (peekchar() == '>')
			ignchar(), c++, ignore(skipwh());
		if (c != 0 && c != 2)
			error("Write forms are 'w' and 'w>>'");
		filename('w');
	} else {
		if (savedfile[0] == 0)
			error("No file|No current filename");
		saddr1=addr1;
		saddr2=addr2;
		addr1=one;
		addr2=dol;
		CP(file, savedfile);
		if (inopen) {
			vclrech(0);
			splitw++;
		}
		lprintf("\"%s\"", file);
	}
	nonexist = stat(file, &stbuf);
	switch (c) {

	case 0:
		if (!exclam && (!value(WRITEANY) || value(READONLY)))
		switch (edfile()) {
		
		case NOTEDF:
			if (nonexist)
				break;
			if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
				if (samei(&stbuf, "/dev/null"))
					break;
				if (samei(&stbuf, "/dev/tty"))
					break;
			}
			io = open(file, O_WRONLY);
			if (io < 0)
				syserror();
			if (!isatty(io))
				serror(" File exists| File exists - use \"w! %s\" to overwrite", file);
			close(io);
			break;

		case EDF:
			if (value(READONLY))
				error(" File is read only");
			break;

		case PARTBUF:
			if (value(READONLY))
				error(" File is read only");
			error(" Use \"w!\" to write partial buffer");
		}
cre:
/*
		synctmp();
*/
#ifdef V6
		io = creat(file, 0644);
#else
		io = creat(file, 0666);
#endif
		if (io < 0)
			syserror();
		writing = 1;
		if (hush == 0) {
			if (nonexist)
				ex_printf(" [New file]");
			else if (value(WRITEANY) && edfile() != EDF)
				ex_printf(" [Existing file]");
		}
		break;

	case 2:
		io = open(file, O_WRONLY);
		if (io < 0) {
			if (exclam || value(WRITEANY))
				goto cre;
			syserror();
		}
		lseek(io, 0l, SEEK_END);
		break;
	}
	putfile();
	ignore(iostats());
	if (c != 2 && addr1 == one && addr2 == dol) {
		if (eq(file, savedfile))
			edited = 1;
		ex_sync();
	}
	if (!dofname) {
		addr1 = saddr1;
		addr2 = saddr2;
	}
	writing = 0;
}
示例#2
0
文件: ex_io.c 项目: n-t-roff/ex-3.6
/*
 * Read a file from the world.
 * C is command, 'e' if this really an edit (or a recover).
 */
void
rop(int c)
{
	register int i;
	struct stat stbuf;
	short magic;
	static int ovro;	/* old value(READONLY) */
	static int denied;	/* 1 if READONLY was set due to file permissions */

	io = open(file, O_RDONLY);
	if (io < 0) {
		if (c == 'e' && errno == ENOENT) {
			edited++;
			/*
			 * If the user just did "ex foo" he is probably
			 * creating a new file.  Don't be an error, since
			 * this is ugly, and it screws up the + option.
			 */
			if (!seenprompt) {
				ex_printf(" [New file]");
				noonl();
				return;
			}
		}
		syserror();
	}
	if (fstat(io, &stbuf))
		syserror();
	switch (stbuf.st_mode & S_IFMT) {

	case S_IFBLK:
		error(" Block special file");

	case S_IFCHR:
		if (isatty(io))
			error(" Teletype");
		if (samei(&stbuf, "/dev/null"))
			break;
		error(" Character special file");

	case S_IFDIR:
		error(" Directory");

	case S_IFREG:
#ifdef CRYPT
		if (xflag)
			break;
#endif
		i = read(io, (char *) &magic, sizeof(magic));
		lseek(io, 0l, SEEK_SET);
		if (i != sizeof(magic))
			break;
		switch (magic) {

		case 0405:	/* Interdata? overlay */
		case 0407:	/* unshared */
		case 0410:	/* shared text */
		case 0411:	/* separate I/D */
		case 0413:	/* VM/Unix demand paged */
		case 0430:	/* PDP-11 Overlay shared */
		case 0431:	/* PDP-11 Overlay sep I/D */
			error(" Executable");

		/*
		 * We do not forbid the editing of portable archives
		 * because it is reasonable to edit them, especially
		 * if they are archives of text files.  This is
		 * especially useful if you archive source files together
		 * and copy them to another system with ~%take, since
		 * the files sometimes show up munged and must be fixed.
		 */
#if 0
		case 0177545:
		case 0177555:
			error(" Archive");
#endif

		default:
#ifndef BIT8
			if (magic & 0100200)
				error(" Non-ascii file");
#endif
			break;
		}
	}
	if (c != 'r') {
		if (value(READONLY) && denied) {
			value(READONLY) = ovro;
			denied = 0;
		}
		if ((stbuf.st_mode & 0222) == 0 || access(file, 2) < 0) {
			ovro = value(READONLY);
			denied = 1;
			value(READONLY) = 1;
		}
	}
	if (value(READONLY)) {
		ex_printf(" [Read only]");
		flush();
	}
	if (c == 'r')
		setdot();
	else
		setall();
	if (FIXUNDO && inopen && c == 'r')
		undap1 = undap2 = dot + 1;
	rop2();
	rop3(c);
}
示例#3
0
/*
 * Write a file.
 */
void
wop(bool dofname)
/* bool dofname;	/ * if 1 call filename, else use savedfile */
{
	register int c, exclam, nonexist;
	line *saddr1, *saddr2;
	struct stat stbuf;
#ifdef	FLOCKFILE
	int *lp, *iop ;
#endif

	c = 0;
	exclam = 0;
	saddr1=addr1;
	saddr2=addr2;
	if (dofname) {
		if (peekchar() == '!')
			exclam++, ignchar();
		ignore(skipwh());
		while (peekchar() == '>')
			ignchar(), c++, ignore(skipwh());
		if (c != 0 && c != 2)
			error("Write forms are 'w' and 'w>>'");
		filename('w');
	} else {
		if (savedfile[0] == 0)
			error("No file|No current filename");
		addr1=one;
		addr2=dol;
		CP(file, savedfile);
		if (inopen) {
			vclrech(0);
			splitw++;
		}
		lprintf("\"%s\"", file);
	}
	nonexist = stat(file, &stbuf);
#ifdef	FLOCKFILE
	/*
	 * if this is either the saved or alternate file or current file,
	 * point to the appropriate descriptor and file lock status.
	 */
	if (strcmp (file,savedfile) == 0) {
		lp = &lock_savedfile ;	iop = &io_savedfile ;
	} else if (strcmp (file,altfile) == 0) {
		lp = &lock_altfile ;	iop = &io_altfile ;
	} else {
		lp = &lock_curr ;	iop = &io_curr ;
	}
	if (!*iop && !nonexist){
		*lp = 0 ;
		if ((*iop = open(file, O_WRONLY)) < 0) *iop = 0 ;
	}
#endif
	switch (c) {

	case 0:
		if (!exclam && (!value(WRITEANY) || value(READONLY)))
		switch (edfile()) {
		
		case NOTEDF:
			if (nonexist)
				break;
			if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
				if (samei(&stbuf, _PATH_DEVNULL))
					break;
				if (samei(&stbuf, _PATH_TTY))
					break;
			}
			io = open(file, O_WRONLY);
			if (io < 0)
				syserror();
			if (!isatty(io))
				serror(" File exists| File exists - use \"w! %s\" to overwrite", file);
			close(io);
			break;

		case EDF:
			if (value(READONLY))
				error(" File is read only");
			break;

		case PARTBUF:
			if (value(READONLY))
				error(" File is read only");
			error(" Use \"w!\" to write partial buffer");
		}
cre:
/*
		synctmp();
*/
#ifdef	FLOCKFILE
	if (*iop && !*lp != LOCK_EX && !exclam) {
		/*
		 * upgrade to a exclusive lock. if can't get, someone else 
		 * has the exclusive lock. bitch to the user.
		 */
		if (flock(*iop, LOCK_EX|LOCK_NB) < 0 && errno == EWOULDBLOCK)
	error (" File being modified by another process - use \"w!\" to write");
		 else *lp = LOCK_EX ;
	}
#endif
#ifdef V6
		io = creat(file, 0644);
#else
		io = creat(file, 0666);
#ifdef vms	/* to retain file protection modes on newer version of file */
		if (!nonexist)
			chmod(file, stbuf.st_mode & 0777);
#endif
#endif
		if (io < 0)
			syserror();
		writing = 1;
		if (hush == 0) {
			if (nonexist)
				ex_printf(" [New file]");
			else if (value(WRITEANY) && edfile() != EDF)
				ex_printf(" [Existing file]");
		}
#ifdef	FLOCKFILE
		if (!*iop)
			*iop = dup(io) ;
#endif
		break;

	case 2:
		io = open(file, O_WRONLY);
		if (io < 0) {
			if (exclam || value(WRITEANY))
				goto cre;
			syserror();
		}
		lseek(io, 0l, SEEK_END);
#ifdef	FLOCKFILE
		if (!*iop) *iop = dup(io) ;
		if (*lp != LOCK_EX && !exclam) {
			/*
		 	 * upgrade to a exclusive lock. if can't get,
			 * someone else has the exclusive lock.
			 * bitch to the user.
		 	 */
			if (flock(*iop, LOCK_SH|LOCK_NB) < 0
			&& errno == EWOULDBLOCK)
				error (
" File being modified by another process - use \"w!>>\" to write");
		 	else *lp = LOCK_EX ;
		}
#endif
		break;
	}
#ifdef	FLOCKFILE
	if (flock(*iop, LOCK_EX|LOCK_NB) >= 0)
		*lp = LOCK_EX ;
#endif
	putfile(0);
#ifndef	vms
	(void) fsync(io);
#endif
	ignore(iostats());
	if (c != 2 && addr1 == one && addr2 == dol) {
		if (eq(file, savedfile))
			edited = 1;
		ex_sync();
	}
	if (!dofname) {
		addr1 = saddr1;
		addr2 = saddr2;
	}
	writing = 0;
}
示例#4
0
/*
 * Read a file from the world.
 * C is command, 'e' if this really an edit (or a recover).
 */
void
rop(int c)
{
	int i;
	struct stat64 stbuf;
	short magic;
	static int ovro;	/* old value(vi_READONLY) */
	static int denied;	/* 1 if READONLY was set due to file permissions */

	io = open(file, 0);
	if (io < 0) {
		if (c == 'e' && errno == ENOENT) {
			edited++;
			/*
			 * If the user just did "ex foo" they're probably
			 * creating a new file.  Don't be an error, since
			 * this is ugly, and it messes up the + option.
			 */
			if (!seenprompt) {
				viprintf(gettext(" [New file]"));
				noonl();
				return;
			}
		}

		if (value(vi_READONLY) && denied) {
			value(vi_READONLY) = ovro;
			denied = 0;
		}
		syserror(0);
	}
	if (fstat64(io, &stbuf))
		syserror(0);
	switch (FTYPE(stbuf) & S_IFMT) {

	case S_IFBLK:
		error(gettext(" Block special file"));
		/* FALLTHROUGH */

	case S_IFCHR:
		if (isatty(io))
			error(gettext(" Teletype"));
		if (samei(&stbuf, "/dev/null"))
			break;
		error(gettext(" Character special file"));
		/* FALLTHROUGH */

	case S_IFDIR:
		error(gettext(" Directory"));

	}
	if (c != 'r') {
		if (value(vi_READONLY) && denied) {
			value(vi_READONLY) = ovro;
			denied = 0;
		}
		if ((FMODE(stbuf) & 0222) == 0 || access((char *)file, 2) < 0) {
			ovro = value(vi_READONLY);
			denied = 1;
			value(vi_READONLY) = 1;
		}
	}
	if (hush == 0 && value(vi_READONLY)) {
		viprintf(gettext(" [Read only]"));
		flush();
	}
	if (c == 'r')
		setdot();
	else
		setall();

	/* If it is a read command, then we must set dot to addr1
	 * (value of N in :Nr ).  In the default case, addr1 will
	 * already be set to dot.
	 *
	 * Next, it is necessary to mark the beginning (undap1) and
	 * ending (undap2) addresses affected (for undo).  Note that
	 * rop2() and rop3() will adjust the value of undap2.
	 */
	if (FIXUNDO && inopen && c == 'r') {
		dot = addr1;
		undap1 = undap2 = dot + 1;
	}
	rop2();
	rop3(c);
}
示例#5
0
/*
 * Read a file from the world.
 * C is command, 'e' if this really an edit (or a recover).
 */
void
rop(int c)
{
	struct stat stbuf;
#ifndef __sun
	register int i;
	struct exec head;
#endif
	static int ovro;	/* old value(READONLY) */
	static int denied;	/* 1 if READONLY was set due to file permissions */
#ifdef	FLOCKFILE
	int *lp, *iop;
#endif

	io = open(file, O_RDONLY);
	if (io < 0) {
		if (c == 'e' && errno == ENOENT) {
			edited++;
			/*
			 * If the user just did "ex foo" he is probably
			 * creating a new file.  Don't be an error, since
			 * this is ugly, and it screws up the + option.
			 */
			if (!seenprompt) {
				ex_printf(" [New file]");
				noonl();
				return;
			}
		}
		syserror();
	}
	if (fstat(io, &stbuf))
		syserror();
	switch (stbuf.st_mode & S_IFMT) {

	case S_IFBLK:
		error(" Block special file");

	case S_IFCHR:
		if (isatty(io))
			error(" Teletype");
		if (samei(&stbuf, _PATH_DEVNULL))
			break;
		error(" Character special file");

	case S_IFDIR:
		error(" Directory");

#ifndef __sun
	case S_IFREG:
#ifdef CRYPT
		if (xflag)
			break;
#endif
		i = read(io, (char *)&head, sizeof(head));
		(void)lseek(io, 0L, L_SET);
		if (i != sizeof(head))
			break;
#ifndef vms
		switch (
#if defined N_MAGIC
		    N_MAGIC(
#elif defined N_GETMAGIC
		    N_GETMAGIC(
#else
# error
#endif
		    head)) {

		case 0405:	/* data overlay on exec */
		case OMAGIC:	/* unshared */
		case NMAGIC:	/* shared text */
		case 0411:	/* separate I/D */
		case ZMAGIC:	/* VM/Unix demand paged */
		case 0430:	/* PDP-11 Overlay shared */
		case 0431:	/* PDP-11 Overlay sep I/D */
			error(" Executable");

		/*
		 * We do not forbid the editing of portable archives
		 * because it is reasonable to edit them, especially
		 * if they are archives of text files.  This is
		 * especially useful if you archive source files together
		 * and copy them to another system with ~%take, since
		 * the files sometimes show up munged and must be fixed.
		 */
		case 0177545:
		case 0177555:
			error(" Archive");
		case 070707:
			error(" Cpio file");

		default:
			{
				char *bp = (char *)&head;
				if ((u_char)bp[0] == (u_char)'\037' &&
				    (u_char)bp[1] == (u_char)'\235')
					error(" Compressed file");
#ifdef ARCHIVES_ARE_OK
				if (!strncmp(bp, "!<arch>\n__.SYMDEF", 17)
				    || !strncmp(bp, "!<arch>\n", 8))
					error(" Archive");
#endif
			}
			break;
		}
#endif /* __sun */
#endif
	}
	if (c != 'r') {
		if (value(READONLY) && denied) {
			value(READONLY) = ovro;
			denied = 0;
		}
		if ((stbuf.st_mode & 0222) == 0 || access(file, 2) < 0) {
			ovro = value(READONLY);
			denied = 1;
			value(READONLY) = 1;
		}
	}
	if (value(READONLY)) {
		ex_printf(" [Read only]");
		flush();
	}
#ifdef	FLOCKFILE
	/*
	 * Attempt to lock the file. We use an sharable lock if reading
	 * the file, and an exclusive lock if editting a file.
	 * The lock will be released when the file is no longer being
	 * referenced. At any time, the editor can have as many as
	 * three files locked, and with different lock statuses.
	 */
	/*
	 * if this is either the saved or alternate file or current file,
	 * point to the appropriate descriptor and file lock status.
	 */
	if (strcmp (file,savedfile) == 0) {
		if (!io_savedfile) io_savedfile = dup(io) ;
		lp = &lock_savedfile ;	iop = &io_savedfile ;
	} else if (strcmp (file,altfile) == 0) {
		if (!io_altfile) io_altfile = dup(io) ;
		lp = &lock_altfile ;	iop = &io_altfile ;
	} else {
		/* throw away current lock, accquire new current lock */
		if (io_curr) close (io_curr) ;
		io_curr = dup(io) ;
		lp = &lock_curr ;	iop = &io_curr ;
		lock_curr = 0 ;
	}
	if (c == 'r' || value(READONLY) || *lp == 0) {
		/* if we have a lock already, don't bother */
		if (!*lp) {
			/* try for a shared lock */
			if (flock(*iop, LOCK_SH|LOCK_NB) < 0
			&& errno == EWOULDBLOCK) {
				ex_printf (
			" [FILE BEING MODIFIED BY ANOTHER PROCESS]") ;
				flush();
				goto fail_lock ;
			} else *lp = LOCK_SH ;
		}
	}
	if ( c != 'r'  && !value(READONLY) && *lp != LOCK_EX) {
		/* if we are editting the file, upgrade to an exclusive lock. */
		if (flock(*iop, LOCK_EX|LOCK_NB) < 0 && errno == EWOULDBLOCK) {
			ex_printf (" [File open by another process]") ;
			flush();
		} else *lp = LOCK_EX ;
	}
fail_lock:
#endif
	if (c == 'r')
		setdot();
	else
		setall();
	if (FIXUNDO && inopen && c == 'r')
		undap1 = undap2 = dot + 1;
	rop2();
	rop3(c);
}