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

📄 io.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE * * is provided to you without charge, and with no warranty.  You may give  * * away copies of JOVE, including sources, provided that this notice is    * * included in all the files.                                              * ***************************************************************************/#include "jove.h"#include "list.h"#include "fp.h"#include "termcap.h"#include "ctype.h"#include "disp.h"#include "scandir.h"#ifdef	IPROCS# include <signal.h>#endif#ifdef	MAC# include "mac.h"#else# include <sys/stat.h>#endif#ifdef	UNIX# include <sys/file.h>#endif#ifdef	MSDOS# include <fcntl.h># include <io.h># include <direct.h># include <dos.h>#endif	/* MSDOS */#include <errno.h>private struct block	*lookup proto((int /* promoted short */));private char#ifdef	MSDOS	*fixpath proto((char *)),#endif	*getblock proto((daddr, bool));private bool	f_getputl proto((struct line *line,struct FileStruct *fp));private void#ifdef	MSDOS	abspath proto((char *, char *)),#endif	file_backup proto((char *fname));#ifdef	MSDOSprivate int	Dchdir proto((char *));#endiflong	io_chars;		/* number of chars in this open_file */int	io_lines;		/* number of lines in this open_file */#ifdef	pdp11char	*iobuff,	*genbuf,	*linebuf;#elsechar	iobuff[LBSIZE],	genbuf[LBSIZE],	linebuf[LBSIZE];#endif#ifdef	BACKUPFILESbool	BkupOnWrite = OFF;#endif#ifndef	MSDOS#define	Dchdir(to)  chdir(to)#else	/* MSDOS */private int			/* chdir + drive */Dchdir(to)char *to;{	unsigned d, dd, n;	if (to[1] == ':') {		d = CharUpcase(to[0]) - 'A';		/* ??? only 16 drives? */		if (d >= 16)			complain("invalid drive");		_dos_getdrive(&dd);		if (dd != d)			_dos_setdrive(d, &n);		if (to[2] == '\0') {			/* ??? Is this correct? DHR			 * Current path on this drive might not be the root.			 */			return 0;		}	}	return chdir(to);}private char *fixpath(p)char *p;{	char *pp = p;	while (*p) {		if (*p == '\\')			*p = '/';		p++;	}	return strlwr(pp);}private voidabspath(so, dest)char *so, *dest;{	char cwd[FILESIZE], cwdD[3], cwdDIR[FILESIZE], cwdF[9], cwdEXT[5],	     soD[3], soDIR[FILESIZE], soF[9], soEXT[5];	char *drive, *path;	_splitpath(fixpath(so), soD, soDIR, soF, soEXT);	getcwd(cwd, FILESIZE);	if (*soD != '\0') {		Dchdir(soD);				/* this is kinda messy	*/		getcwd(cwdDIR, FILESIZE);	/* should probably just	*/		Dchdir(cwd);				/* call DOS to do it	*/		strcpy(cwd, cwdDIR);	}	(void) fixpath(cwd);	if (cwd[strlen(cwd)-1] != '/')		strcat(cwd, "/x.x");	/* need dummy filename */	_splitpath(fixpath(cwd), cwdD, cwdDIR, cwdF, cwdEXT);	drive = (*soD == '\0') ? cwdD : soD;	if (*soDIR != '/')		path = strcat(cwdDIR, soDIR);	else		path = soDIR;	_makepath(dest, drive, path, soF, soEXT);	fixpath(dest);	/* can't do it often enough */}#endif	/* MSDOS */voidclose_file(fp)File	*fp;{	if (fp) {		if (fp->f_flags & F_TELLALL)			add_mess(" %d lines, %D characters.",				 io_lines,				 io_chars);		f_close(fp);	}}/* Write the region from line1/char1 to line2/char2 to FP.  This   never CLOSES the file since we don't know if we want to. */bool	EndWNewline = 1;voidputreg(fp, line1, char1, line2, char2, makesure)register File	*fp;Line	*line1,	*line2;int	char1,	char2;bool	makesure;{	register int	c;	register char	*lp;	if (makesure)		(void) fixorder(&line1, &char1, &line2, &char2);	while (line1 != line2->l_next) {		lp = lcontents(line1) + char1;		if (line1 == line2) {			fputnchar(lp, (char2 - char1), fp);			io_chars += (char2 - char1);		} else {			while ((c = *lp++) != '\0') {				jputc(c, fp);				io_chars += 1;			}		}		if (line1 != line2) {			io_lines += 1;			io_chars += 1;#ifdef	MSDOS			jputc('\r', fp);#endif	/* MSDOS */			jputc('\n', fp);		}		line1 = line1->l_next;		char1 = 0;	}	flushout(fp);}private voiddofread(fp)register File	*fp;{	char	end[LBSIZE];	bool	xeof;	Line	*savel = curline;	int	savec = curchar;	strcpy(end, linebuf + curchar);	xeof = f_gets(fp, linebuf + curchar, (size_t) (LBSIZE - curchar));	SavLine(curline, linebuf);	while(!xeof) {		curline = listput(curbuf, curline);		xeof = f_getputl(curline, fp);	}	getDOT();	linecopy(linebuf, (curchar = strlen(linebuf)), end);	SavLine(curline, linebuf);	IFixMarks(savel, savec, curline, curchar);}voidread_file(file, is_insert)char	*file;bool	is_insert;{	Bufpos	save;	File	*fp;	int	rdonly;	if (!is_insert)		curbuf->b_ntbf = NO;	fp = open_file(file, iobuff, F_READ, NO, NO);	if (fp == NULL) {		if (!is_insert && errno == ENOENT)			s_mess("(new file)");		else			s_mess(IOerr("open", file));		return;	}	rdonly = (fp->f_flags & F_READONLY)? 1 : 0;	DOTsave(&save);	dofread(fp);	if (is_insert && io_chars > 0) {		modify();		set_mark();	}	SetDot(&save);	getDOT();	close_file(fp);	/* just guessing that if this is moved here */	/* then the bug on SunOS that seems to alter */	/* mtime under our feet will disappear */	if (!is_insert) {		set_ino(curbuf);		set_arg_value(rdonly);		TogMinor(ReadOnly);	}}voidSaveFile(){	if (IsModified(curbuf)) {		if (curbuf->b_fname == NULL)			WriteFile();		else {			filemunge(curbuf->b_fname);			chk_mtime(curbuf, curbuf->b_fname, "save");			file_write(curbuf->b_fname, NO);		}	} else		message("No changes need to be written.");}char	*HomeDir;	/* home directory */size_t	HomeLen;	/* length of home directory string */private List		*DirStack = NULL;#define dir_name(dp)	((char *) list_data((dp)))#define PWD_PTR		(list_data(DirStack))#define PWD		((char *) PWD_PTR)char *pwd(){	return (char *) PWD_PTR;}char *pr_name(fname, okay_home)char	*fname;int	okay_home;{	int	n;	if (fname != NULL) {		n = numcomp(fname, PWD);		if ((PWD[n] == '\0') &&	/* Matched to end of PWD */		    (fname[n] == '/'))			return fname + n + 1;		if (okay_home && strcmp(HomeDir, "/") != 0		&& strncmp(fname, HomeDir, HomeLen) == 0		&& fname[HomeLen] == '/')		{			static char	name_buf[100];			swritef(name_buf, sizeof(name_buf),				"~%s", fname + HomeLen);			return name_buf;		}	}	return fname;}voidChdir(){	char	dirbuf[FILESIZE];#ifdef	MSDOS	fmask = 0x10;#endif	(void) ask_file((char *)NULL, PWD, dirbuf);#ifdef	MSDOS	fmask = 0x13;#endif	if (Dchdir(dirbuf) == -1)	{		s_mess("cd: cannot change into %s.", dirbuf);		return;	}	UpdModLine = YES;	setCWD(dirbuf);	prCWD();#ifdef	MAC	Bufchange = YES;#endif}#ifdef	UNIX#  ifndef	BSD4_2char *getwd(buffer)char	*buffer;{	Buffer	*old = curbuf;	char	*ret_val;	SetBuf(do_select((Window *)NULL, "pwd-output"));	curbuf->b_type = B_PROCESS;	(void) UnixToBuf("pwd-output", (char *)NULL, NO, 0, YES,		"/bin/pwd", (char *) NULL);	ToFirst();	strcpy(buffer, linebuf);	SetBuf(old);	return buffer;}#  endif	/* not BSD4_2 *//* Check if dn is the name of the current working directory   and that it is in cannonical form */boolchkCWD(dn)char	*dn;{	char	filebuf[FILESIZE];	struct stat	dnstat,			dotstat;	if (dn[0] != '/')		return FALSE;		/* need absolute pathname */	PathParse(dn, filebuf);	return stat(filebuf, &dnstat) == 0 &&	       stat(".", &dotstat) == 0 &&	       dnstat.st_dev == dotstat.st_dev &&	       dnstat.st_ino == dotstat.st_ino;}#endif	/* UNIX */voidsetCWD(d)char	*d;{	if (DirStack == NULL)		list_push(&DirStack, (UnivPtr)NULL);	PWD_PTR = (PWD == NULL)		? (UnivPtr) emalloc((size_t) (strlen(d) + 1))		: (UnivPtr) freealloc((UnivPtr) PWD, strlen(d) + 1);	strcpy(PWD, d);}voidgetCWD(){	char	*cwd;	char	pathname[FILESIZE];#ifndef	MSDOS	cwd = getenv("CWD");	if (cwd == NULL || !chkCWD(cwd)) {		cwd = getenv("PWD");		if (cwd == NULL || !chkCWD(cwd)) {#ifdef	HAVE_GETWD			cwd = getwd(pathname);#else			/* System Vr4, and who else? */			extern char	*getcwd proto((char *, int/*!!!*/));			cwd = getcwd(pathname, (int) sizeof(pathname));#endif	/* HAVE_GETWD */		}	}#else	/* MSDOS */	{	    extern char	*getcwd();	    cwd = fixpath(getcwd(pathname, FILESIZE));	}#endif	/* MSDOS */	setCWD(cwd);}voidprDIRS(){	register List	*lp;	s_mess(": %f ");	for (lp = DirStack; lp != NULL; lp = list_next(lp))		add_mess("%s ", pr_name(dir_name(lp), YES));}voidprCWD(){	s_mess(": %f => \"%s\"", PWD);}voidPushd(){	char	*newdir,		dirbuf[FILESIZE];#ifdef	MSDOS	fmask = 0x10;#endif	newdir = ask_file((char *)NULL, NullStr, dirbuf);#ifdef	MSDOS	fmask = 0x13;#endif	UpdModLine = YES;	if (*newdir == '\0') {	/* Wants to swap top two entries */		char	*old_top;		if (list_next(DirStack) == NULL)			complain("pushd: no other directory.");		old_top = PWD;		list_data(DirStack) = (UnivPtr) dir_name(list_next(DirStack));		list_data(list_next(DirStack)) = (UnivPtr) old_top;		(void) Dchdir(PWD);	} else {		if (Dchdir(dirbuf) == -1)		{			s_mess("pushd: cannot change into %s.", dirbuf);			return;		}		(void) list_push(&DirStack, (UnivPtr)NULL);		setCWD(dirbuf);	}	prDIRS();}voidPopd(){	if (list_next(DirStack) == NULL)		complain("popd: directory stack is empty.");	UpdModLine = YES;	free((UnivPtr) list_pop(&DirStack));	(void) Dchdir(PWD);	/* If this doesn't work, we's in deep shit. */	prDIRS();}private voiddfollow(file, into)char	*file,	*into;{	char	*dp,		*sp;#ifndef	MSDOS	if (*file == '/') {		/* Absolute pathname */		strcpy(into, "/");		file += 1;	} else {		strcpy(into, PWD);	}#else	/* MSDOS */	char	filefix[FILESIZE];	abspath(file, filefix);		/* convert to absolute pathname */	strcpy(into, filefix);		/* and forget about drives	*/	into[3] = '\0';	into = &(into[2]);	file = &(filefix[3]);#endif	/* MSDOS */	dp = into + strlen(into);	for (;;) {		if (*file == '\0')			break;		if ((sp = strchr(file, '/')) != NULL)			*sp = '\0';		if (*file == '\0' || strcmp(file, ".") == 0) {			/* So it will get to the end of the loop */		} else if (strcmp(file, "..") == 0) {			for (;;) {			    if (dp == into) {				*dp++ = '/';				break;			    }			    if (*--dp == '/')				break;			}			*dp = '\0';		} else {			if (dp!=into && dp[-1]!='/')			    *dp++ = '/';			strcpy(dp, file);			dp += strlen(dp);	/* stay at the end */		}		if (sp == NULL)		    break;		file = sp + 1;	}}#ifdef	UNIX# ifdef	YP_PASSWD#include <pwd.h>private voidget_hdir(user, buf)register char	*user,		*buf;{	struct passwd	*p;	p = getpwnam(user);	endpwent();	if (p == NULL) {		add_mess(" [unknown user: %s]", user);		SitFor(7);		complain((char *)NULL);		/* NOTREACHED */	}	strcpy(buf, p->pw_dir);}#else#include "re.h"private voidget_hdir(user, buf)register char	*user,		*buf;{	char	fbuf[LBSIZE],		pattern[100];	register int	u_len;	File	*fp;	u_len = strlen(user);	fp = open_file("/etc/passwd", fbuf, F_READ, YES, YES);	swritef(pattern, sizeof(pattern),		"%s:[^:]*:[^:]*:[^:]*:[^:]*:\\([^:]*\\):", user);	while (!f_gets(fp, genbuf, LBSIZE))		if ((strncmp(genbuf, user, u_len) == 0)		&& LookingAt(pattern, genbuf, 0)) {			putmatch(1, buf, FILESIZE);			close_file(fp);			return;		}	close_file(fp);	add_mess(" [unknown user: %s]", user);	SitFor(7);	complain((char *)NULL);}#endif	/* YP_PASSWD */#endif	/* UNIX */voidPathParse(name, intobuf)char	*name,	*intobuf;{	char	localbuf[FILESIZE];	intobuf[0] = localbuf[0] = '\0';	if (*name == '\0')		return;	if (*name == '~') {		if (name[1] == '/' || name[1] == '\0') {			strcpy(localbuf, HomeDir);			name += 1;		}#ifdef	UNIX	/* may add for mac in future */		else {			char	*uendp = strchr(name, '/'),				unamebuf[30];			if (uendp == NULL)				uendp = name + strlen(name);			name += 1;			null_ncpy(unamebuf, name, (size_t) (uendp - name));			get_hdir(unamebuf, localbuf);			name = uendp;		}#endif#ifndef	MSDOS	} else if (*name == '\\') {		/* allow quoting of ~ (but \ is a path separator in MSDOS) */		name += 1;#endif	/* MSDOS */	}	(void) strcat(localbuf, name);	dfollow(localbuf, intobuf);}voidfilemunge(newname)char	*newname;{	struct stat	stbuf;	if (newname == NULL)		return;	if (stat(newname, &stbuf))		return;	if (#ifndef	MSDOS	    ((stbuf.st_dev != curbuf->b_dev) ||	     (stbuf.st_ino != curbuf->b_ino)) &&#endif	/* !MSDOS */#ifndef	MAC	    ((stbuf.st_mode & S_IFMT) != S_IFCHR) &&#endif	/* !MAC */	    (curbuf->b_fname==NULL || strcmp(newname, curbuf->b_fname) != 0)) {		rbell();		confirm("\"%s\" already exists; overwrite it? ", newname);	}}int	CreatMode = DFLT_MODE;private voidDoWriteReg(app)bool	app;{	char	fnamebuf[FILESIZE],		*fname;	Mark	*mp = CurMark();	File	*fp;	/* Won't get here if there isn't a Mark */	fname = ask_file((char *)NULL, (char *)NULL, fnamebuf);#ifdef	BACKUPFILES	if (app == NO) {		filemunge(fname);		if (BkupOnWrite)			file_backup(fname);	}#else	if (!app)		filemunge(fname);#endif	fp = open_file(fname, iobuff, app ? F_APPEND : F_WRITE, YES, NO);	putreg(fp, mp->m_line, mp->m_char, curline, curchar, YES);	close_file(fp);}voidWrtReg(){	DoWriteReg(NO);}voidAppReg(){	DoWriteReg(YES);}bool	OkayBadChars = NO;voidWriteFile(){	char	*fname,

⌨️ 快捷键说明

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