xref: /csrg-svn/usr.bin/mail/edit.c (revision 1472)
11228Skas #
21228Skas 
31228Skas #include "rcv.h"
41228Skas #include <stdio.h>
51228Skas #include <sys/stat.h>
61228Skas 
71228Skas /*
81228Skas  * Mail -- a mail program
91228Skas  *
101228Skas  * Perform message editing functions.
111228Skas  */
121228Skas 
13*1472Skas static char *SccsId = "@(#)edit.c	1.2 10/16/80";
141228Skas 
151228Skas /*
161228Skas  * Edit a message list.
171228Skas  */
181228Skas 
191228Skas editor(msgvec)
201228Skas 	int *msgvec;
211228Skas {
221228Skas 	char *edname;
231228Skas 
241228Skas 	if ((edname = value("EDITOR")) == NOSTR)
251228Skas 		edname = EDITOR;
261228Skas 	return(edit1(msgvec, edname));
271228Skas }
281228Skas 
291228Skas /*
301228Skas  * Invoke the visual editor on a message list.
311228Skas  */
321228Skas 
331228Skas visual(msgvec)
341228Skas 	int *msgvec;
351228Skas {
361228Skas 	char *edname;
371228Skas 
381228Skas 	if ((edname = value("VISUAL")) == NOSTR)
391228Skas 		edname = VISUAL;
401228Skas 	return(edit1(msgvec, edname));
411228Skas }
421228Skas 
431228Skas /*
441228Skas  * Edit a message by writing the message into a funnily-named file
451228Skas  * (which should not exist) and forking an editor on it.
461228Skas  * We get the editor from the stuff above.
471228Skas  */
481228Skas 
491228Skas edit1(msgvec, ed)
501228Skas 	int *msgvec;
511228Skas 	char *ed;
521228Skas {
531228Skas 	register char *cp, *cp2;
541228Skas 	register int c;
551228Skas 	int *ip, pid, mesg, lines;
561228Skas 	unsigned int ms;
571228Skas 	int (*sigint)(), (*sigquit)();
581228Skas 	FILE *ibuf, *obuf;
591228Skas 	char edname[15], nbuf[10];
601228Skas 	struct message *mp;
611228Skas 	extern char tempEdit[];
621228Skas 	off_t fsize(), size;
631228Skas 	struct stat statb;
641228Skas 	long modtime;
651228Skas 
661228Skas 	/*
671228Skas 	 * Set signals; locate editor.
681228Skas 	 */
691228Skas 
701228Skas 	sigint = signal(SIGINT, SIG_IGN);
711228Skas 	sigquit = signal(SIGQUIT, SIG_IGN);
721228Skas 
731228Skas 	/*
741228Skas 	 * Deal with each message to be edited . . .
751228Skas 	 */
761228Skas 
771228Skas 	for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
781228Skas 		mesg = *ip;
791228Skas 		mp = &message[mesg-1];
801228Skas 		mp->m_flag |= MODIFY;
811228Skas 
821228Skas 		/*
831228Skas 		 * Make up a name for the edit file of the
841228Skas 		 * form "Message%d" and make sure it doesn't
851228Skas 		 * already exist.
861228Skas 		 */
871228Skas 
881228Skas 		cp = &nbuf[10];
891228Skas 		*--cp = 0;
901228Skas 		while (mesg) {
911228Skas 			*--cp = mesg % 10 + '0';
921228Skas 			mesg /= 10;
931228Skas 		}
941228Skas 		cp2 = copy("Message", edname);
951228Skas 		while (*cp2++ = *cp++)
961228Skas 			;
971228Skas 		if (!access(edname, 2)) {
981228Skas 			printf("%s: file exists\n", edname);
991228Skas 			goto out;
1001228Skas 		}
1011228Skas 
1021228Skas 		/*
1031228Skas 		 * Copy the message into the edit file.
1041228Skas 		 */
1051228Skas 
1061228Skas 		close(creat(edname, 0600));
1071228Skas 		if ((obuf = fopen(edname, "w")) == NULL) {
1081228Skas 			perror(edname);
1091228Skas 			goto out;
1101228Skas 		}
1111228Skas 		if (send(mp, obuf) < 0) {
1121228Skas 			perror(edname);
1131228Skas 			fclose(obuf);
1141228Skas 			remove(edname);
1151228Skas 			goto out;
1161228Skas 		}
1171228Skas 		fflush(obuf);
1181228Skas 		if (ferror(obuf)) {
1191228Skas 			remove(edname);
1201228Skas 			fclose(obuf);
1211228Skas 			goto out;
1221228Skas 		}
1231228Skas 		fclose(obuf);
1241228Skas 
1251228Skas 		/*
126*1472Skas 		 * If we are in read only mode, make the
127*1472Skas 		 * temporary message file readonly as well.
128*1472Skas 		 */
129*1472Skas 
130*1472Skas 		if (readonly)
131*1472Skas 			chmod(edname, 0400);
132*1472Skas 
133*1472Skas 		/*
1341228Skas 		 * Fork/execl the editor on the edit file.
1351228Skas 		 */
1361228Skas 
1371228Skas 		if (stat(edname, &statb) < 0)
1381228Skas 			modtime = 0;
1391228Skas 		modtime = statb.st_mtime;
1401228Skas 		pid = vfork();
1411228Skas 		if (pid == -1) {
1421228Skas 			perror("fork");
1431228Skas 			remove(edname);
1441228Skas 			goto out;
1451228Skas 		}
1461228Skas 		if (pid == 0) {
1471228Skas 			if (sigint != SIG_IGN)
1481228Skas 				signal(SIGINT, SIG_DFL);
1491228Skas 			if (sigquit != SIG_IGN)
1501228Skas 				signal(SIGQUIT, SIG_DFL);
1511228Skas 			execl(ed, ed, edname, 0);
1521228Skas 			perror(ed);
1531228Skas 			_exit(1);
1541228Skas 		}
1551228Skas 		while (wait(&mesg) != pid)
1561228Skas 			;
1571228Skas 
1581228Skas 		/*
159*1472Skas 		 * If in read only mode, just remove the editor
160*1472Skas 		 * temporary and return.
161*1472Skas 		 */
162*1472Skas 
163*1472Skas 		if (readonly) {
164*1472Skas 			remove(edname);
165*1472Skas 			continue;
166*1472Skas 		}
167*1472Skas 
168*1472Skas 		/*
1691228Skas 		 * Now copy the message to the end of the
1701228Skas 		 * temp file.
1711228Skas 		 */
1721228Skas 
1731228Skas 		if (stat(edname, &statb) < 0) {
1741228Skas 			perror(edname);
1751228Skas 			goto out;
1761228Skas 		}
1771228Skas 		if (modtime == statb.st_mtime) {
1781228Skas 			remove(edname);
1791228Skas 			goto out;
1801228Skas 		}
1811228Skas 		if ((ibuf = fopen(edname, "r")) == NULL) {
1821228Skas 			perror(edname);
1831228Skas 			remove(edname);
1841228Skas 			goto out;
1851228Skas 		}
1861228Skas 		remove(edname);
1871228Skas 		fseek(otf, (long) 0, 2);
1881228Skas 		size = fsize(otf);
1891228Skas 		mp->m_block = blockof(size);
1901228Skas 		mp->m_offset = offsetof(size);
1911228Skas 		ms = 0;
1921228Skas 		lines = 0;
1931228Skas 		while ((c = getc(ibuf)) != EOF) {
1941228Skas 			if (c == '\n')
1951228Skas 				lines++;
1961228Skas 			putc(c, otf);
1971228Skas 			if (ferror(otf))
1981228Skas 				break;
1991228Skas 			ms++;
2001228Skas 		}
2011228Skas 		mp->m_size = ms;
2021228Skas 		mp->m_lines = lines;
2031228Skas 		if (ferror(otf))
2041228Skas 			perror("/tmp");
2051228Skas 		fclose(ibuf);
2061228Skas 	}
2071228Skas 
2081228Skas 	/*
2091228Skas 	 * Restore signals and return.
2101228Skas 	 */
2111228Skas 
2121228Skas out:
2131228Skas 	signal(SIGINT, sigint);
2141228Skas 	signal(SIGQUIT, sigquit);
2151228Skas }
216