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

📄 ufile.c

📁 举世闻名的joe记事本源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 	User file operations *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"#ifdef UTIME#include <utime.h>#define HAVEUTIME 1#else#ifdef SYSUTIME#include <sys/utime.h>#define HAVEUTIME 1#endif#endif#ifdef WITH_SELINUXint copy_security_context(const char *from_file, const char *to_file);#endifint orphan;unsigned char *backpath = NULL;		/* Place to store backup files */B *filehist = NULL;	/* History of file names */int nobackups = 0;int exask = 0;/* Ending message generator *//**** message which is shown after closing joe (CTRL+x; CTRL+k) *****/void genexmsg(BW *bw, int saved, unsigned char *name){	unsigned char *s;	if (bw->b->name && bw->b->name[0]) {		s = bw->b->name;	} else {		s = joe_gettext(_("(Unnamed)"));	}	if (name) {		if (saved) {			joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("File %s saved")), name);		} else {			joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("File %s not saved")), name);		}	} else if (bw->b->changed && bw->b->count == 1) {		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("File %s not saved")), s);	} else if (saved) {		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("File %s saved")), s);	} else {		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("File %s not changed so no update needed")), s);	}	if (exmsg)		vsrm(exmsg);	exmsg = vsncpy(NULL,0,sz(msgbuf));	msgnw(bw->parent, msgbuf);}/* For ^X ^C */void genexmsgmulti(BW *bw, int saved, int skipped){	if (saved)		if (skipped)			joe_snprintf_0(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("Some files have not been saved.")));		else			joe_snprintf_0(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("All modified files have been saved.")));	else		joe_snprintf_0(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("No modified files, so no updates needed.")));	msgnw(bw->parent, msgbuf);	exmsg = vsncpy(NULL,0,sz(msgbuf));}/* Shell escape */int ushell(BW *bw){	nescape(bw->parent->t->t);	ttsusp();	nreturn(bw->parent->t->t);	return 0;}/* Execute shell command */static int dosys(BW *bw, unsigned char *s, void *object, int *notify){	int rtn;	nescape(bw->parent->t->t);	rtn=ttshell(s);	nreturn(bw->parent->t->t);	if (notify)		*notify = 1;	vsrm(s);	return rtn;}int usys(BW *bw){	if (wmkpw(bw->parent, joe_gettext(_("System (^C to abort): ")), NULL, dosys, NULL, NULL, NULL, NULL, NULL, bw->b->o.charmap, 1))		return 0;	else		return -1;}/* Copy a file */static int cp(unsigned char *from, unsigned char *to){	int f, g, amnt;	struct stat sbuf;#ifdef HAVEUTIME#ifdef NeXT	time_t utbuf[2];#else	struct utimbuf utbuf;#endif#endif	f = open((char *)from, O_RDONLY);	if (f < 0) {		return -1;	}	if (fstat(f, &sbuf) < 0) {		return -1;	}	g = creat((char *)to, sbuf.st_mode & ~(S_ISUID | S_ISGID));	if (g < 0) {		close(f);		return -1;	}	while ((amnt = read(f, stdbuf, stdsiz)) > 0) {		if (amnt != joe_write(g, stdbuf, amnt)) {			break;		}	}	close(f);	close(g);	if (amnt) {		return -1;	}#ifdef HAVEUTIME#ifdef NeXT	utbuf[0] = (time_t) sbuf.st_atime;	utbuf[1] = (time_t) sbuf.st_mtime;#else	utbuf.actime = sbuf.st_atime;	utbuf.modtime = sbuf.st_mtime;#endif	utime(to, &utbuf);#endif#ifdef WITH_SELINUX	copy_security_context(from,to);#endif	return 0;}/* Make backup file if it needs to be made * Returns 0 if backup file was made or didn't need to be made * Returns 1 for error */static int backup(BW *bw){	if (!bw->b->backup && !nobackups && bw->b->name && bw->b->name[0]) {		unsigned char tmp[1024];		unsigned char name[1024];#ifdef __MSDOS__		int x;		if (backpath) {			unsigned char *t = vsncpy(NULL,0,sz(backpath));			t = canonical(t);			joe_snprintf_2(name, sizeof(name), "%s/%s", t, namepart(tmp, bw->b->name));			vsrm(t);		} else {			joe_snprintf_1(name, sizeof(name), "%s", bw->b->name);		}		for (x = zlen(name); name[--x] != '.';) {			if (name[x] == '\\' || (name[x] == ':' && x == 1) || x == 0) {				x = zlen(name);				break;			}		}		zcpy(name + x, USTR ".bak");#else		/* Create backup file name */		unsigned char *simple_backup_suffix = (unsigned char *)getenv("SIMPLE_BACKUP_SUFFIX");				if (simple_backup_suffix == NULL) {			simple_backup_suffix = USTR "~";		}		if (backpath) {			unsigned char *t = vsncpy(NULL, 0, sz(backpath));			t = canonical(t);			joe_snprintf_3(name, sizeof(name), "%s/%s%s", t, namepart(tmp, bw->b->name), simple_backup_suffix);			vsrm(t);		} else {			joe_snprintf_2(name, sizeof(name), "%s%s", bw->b->name, simple_backup_suffix);		}				/* Attempt to delete backup file first */		unlink((char *)name);#endif		/* Copy original file to backup file */		if (cp(bw->b->name, name)) {			return 1;		} else {			bw->b->backup = 1;			return 0;		}	} else {		return 0;	}}/* Write file *//* Continuation structure */struct savereq {	int (*callback) ();	unsigned char *name;	B *first;	int not_saved;	/* Set if a modified file was not saved */	int rename;	/* Set if we're renaming the file during save */	int block_save; /* Flag, if we want to save a block# */	unsigned char *message; /* String for messages to be shown to the user */};struct savereq *mksavereq(int (*callback)(), unsigned char *name, B *first,int rename, int block_save){	struct savereq *req = (struct savereq *) joe_malloc(sizeof(struct savereq));	req->callback = callback;	req->name = name;	req->first = first;	req->not_saved = 0;	req->rename = rename;	req->block_save = block_save;	return req;}static void rmsavereq(struct savereq *req){	vsrm(req->name);	joe_free(req);}/* Check if character 'c' is in the set. * 'c' should be unicode if the locale is UTF-8, otherwise it's * an 8-bit character.  'set' should be of this format: "xxxx<>yyyy".  xxxx * is a list of 8-bit characters. yyyy is a list of UTF-8 characters. */unsigned char *yes_key = (unsigned char *) _("|yes|yY");unsigned char *no_key = (unsigned char *) _("|no|nN");int yncheck(unsigned char *key_set, int c){	unsigned char *set = joe_gettext(key_set);	if (locale_map->type) {		/* 'c' is unicode */		while (*set) {			if (c == utf8_decode_fwrd(&set, NULL))				return 1;		}		return 0;	} else {		/* 'c' is 8-bit */		while (set[0]) {			if (set[0] == c)				return 1;			++set;		}		return 0;	}}int ynchecks(unsigned char *set, unsigned char *s){	if (locale_map->type)		return yncheck(set, utf8_decode_fwrd(&s, NULL));	else		return yncheck(set, s[0]);}static int saver(BW *bw, int c, struct savereq *req, int *notify){	int fl;	if (c == NO_CODE || yncheck(no_key, c)) {		msgnw(bw->parent, joe_gettext(_("Couldn't make backup file... file not saved")));		if (req->callback) {			return req->callback(bw, req, -1, notify);		} else {			if (notify) {				*notify = 1;			}			rmsavereq(req);			return -1;		}	}	if (c != YES_CODE && !yncheck(yes_key, c)) {		if (mkqw(bw->parent, sz(joe_gettext(_("Could not make backup file.  Save anyway (y,n,^C)? "))), saver, NULL, req, notify)) {			return 0;		} else {			rmsavereq(req);			if (notify)				*notify = 1;			return -1;		}	}	if (bw->b->er == -1 && bw->o.msnew) {		exmacro(bw->o.msnew,1);		bw->b->er = -3;	}	if (bw->b->er == 0 && bw->o.msold) {		exmacro(bw->o.msold,1);	}	if ((fl = bsave(bw->b->bof, req->name, bw->b->eof->byte, 1)) != 0) {		msgnw(bw->parent, joe_gettext(msgs[-fl]));		if (req->callback) {			return req->callback(bw, req, -1, notify);		} else {			rmsavereq(req);			if (notify) {				*notify = 1;			}			return -1;		}	} else {		if (req->rename) {			joe_free(bw->b->name);			bw->b->name = 0;		}		if (!bw->b->name && req->name[0]!='!' && req->name[0]!='>')			bw->b->name = joesep(zdup(req->name));		if (bw->b->name && !zcmp(bw->b->name, req->name)) {			bw_unlock(bw);			bw->b->changed = 0;			saverr(bw->b->name);		}		{			/* Last UNDOREC which wasn't modified will be changed			 * to modified. And because this block is			 * executed after each 'save', there can't be more			 * than one record which is not modified			 *		24 Apr 2001, Marx			 */			UNDO *u = bw->b->undo;			UNDOREC *rec, *rec_start;			rec = rec_start = &u->recs;			do {				rec = rec->link.prev;			} while (rec != rec_start && rec->changed);			if(rec->changed == 0)				rec->changed = 1;		}		genexmsg(bw, 1, req->name);		if (req->callback) {			return req->callback(bw, req, 0, notify);		} else {			rmsavereq(req);			return 0;		}	}}static int dosave(BW *bw, struct savereq *req, int *notify){	if (req->block_save)	{		if (notify)			*notify = 1;		if (markv(1)) {			if (square) {				int fl;				int ret = 0;				B *tmp = pextrect(markb,						  markk->line - markb->line + 1,						  markk->xcol);						  				if ((fl = bsave(tmp->bof, req->name, tmp->eof->byte, 0)) != 0) {					msgnw(bw->parent, joe_gettext(msgs[-fl]));					ret = -1;				}				brm(tmp);				if (!ret) {					joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("Block written to file %s")), req->name);					msgnw(bw->parent, msgbuf);				}				if (lightoff)					unmark(bw);				vsrm(req->name);				return ret;			} else {				int fl;				int ret = 0;				if ((fl = bsave(markb, req->name, markk->byte - markb->byte, 0)) != 0) {					msgnw(bw->parent, joe_gettext(msgs[-fl]));					ret = -1;				}				if (!ret) {					joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("Block written to file %s")), req->name);					msgnw(bw->parent, msgbuf);				}				if (lightoff)					unmark(bw);					vsrm(req->name);				return ret;			}		} else {			vsrm(req->name);			msgnw(bw->parent, joe_gettext(_("No block")));			return -1;		}	}	else	{		if (backup(bw)) {			return saver(bw, 0, req, notify);		} else {			return saver(bw, YES_CODE, req, notify);		}	}}static int dosave2(BW *bw, int c, struct savereq *req, int *notify){	if (c == YES_CODE || yncheck(yes_key, c)) {		return dosave(bw, req, notify);	} else if (c == NO_CODE || yncheck(no_key, c)) {		if (notify) {			*notify = 1;		}		genexmsg(bw, 0, req->name);		rmsavereq(req);		return -1;	} else if (mkqw(bw->parent, sz(req->message), dosave2, NULL, req, notify)) {		return 0;	} else {		/* Should be in abort function */		rmsavereq(req);		return -1;	}}/* Checks if file exists. */static int dosave1(BW *bw, unsigned char *s, struct savereq *req, int *notify){	int f;	if (req->name)		vsrm(req->name);	req->name = s;	if (s[0] != '!' && !(s[0] == '>' && s[1] == '>')) {		/* It's a normal file: not a pipe or append */		if (!bw->b->name || zcmp(s, bw->b->name)) {			/* Newly named file or name is different than buffer */			f = open((char *)s, O_RDONLY);			if (f != -1) {				close(f);				/* char *msg = "File exists. Overwrite (y,n,^C)? ";				   req->message = msg; */				req->message = joe_gettext(_("File exists. Overwrite (y,n,^C)? "));				return dosave2(bw, 0, req, notify);			}		}		else {			/* We're saving a newer version of the same file */			if (check_mod(bw->b)) {				req->message = joe_gettext(_("File on disk is newer. Overwrite (y,n,^C)? "));				return dosave2(bw, 0, req, notify);			}		}	}	return dosave(bw, req, notify);}/* User command: ^K D */int usave(BW *bw){	BW *pbw;		pbw = wmkpw(bw->parent, joe_gettext(_("Name of file to save (^C to abort): ")), &filehist, dosave1, USTR "Names", NULL, cmplt,	            mksavereq(NULL,NULL,NULL,0, 0), NULL, locale_map, bw->b->name ? 1 : 7);	if (pbw && bw->b->name) {		binss(pbw->cursor, bw->b->name);		pset(pbw->cursor, pbw->b->eof);		pbw->cursor->xcol = piscol(pbw->cursor);	}	if (pbw) {		return 0;	} else {		return -1;	}}int usavenow(BW *bw){	if (bw->b->name) {		return dosave1(bw,vsncpy(NULL,0,sz(bw->b->name)),mksavereq(NULL,NULL,NULL,0,0),NULL);	} else		return usave(bw);}/* Write highlighted block to a file */int ublksave(BW *bw){	if (markb && markk && markb->b == markk->b && (markk->byte - markb->byte) > 0 && (!square || piscol(markk) > piscol(markb))) {		if (wmkpw(bw->parent, joe_gettext(_("Name of file to write (^C to abort): ")), &filehist, dosave1, USTR "Names", NULL, cmplt, mksavereq(NULL, NULL, NULL, 0, 1), NULL, locale_map, 3)) {			return 0;		} else {			return -1;		}	} else {		return usave(bw);	}}/* Load file to edit */int doedit1(BW *bw,int c,unsigned char *s,int *notify){	int omid;	int ret = 0;	int er;	void *object;	W *w;	B *b;	if (c == YES_CODE || yncheck(yes_key, c)) {		/* Reload from file */		if (notify) {			*notify = 1;		}		b = bfind_reload(s);		er = berror;		if (bw->b->count == 1 && (bw->b->changed || bw->b->name)) {			if (orphan) {				orphit(bw);			} else {				if (uduptw(bw)) {					brm(b);					return -1;				}				bw = (BW *) maint->curwin->object;			}		}		if (er) {			msgnwt(bw->parent, joe_gettext(msgs[-er]));			if (er != -1) {				ret = -1;			}		}		object = bw->object;		w = bw->parent;		bwrm(bw);		w->object = (void *) (bw = bwmk(w, b, 0));		wredraw(bw->parent);		bw->object = object;		vsrm(s);		if (er == -1 && bw->o.mnew) {			exmacro(bw->o.mnew,1);		}		if (er == 0 && bw->o.mold) {			exmacro(bw->o.mold,1);

⌨️ 快捷键说明

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