122451Sdist /* 222451Sdist * Copyright (c) 1980 Regents of the University of California. 333499Sbostic * All rights reserved. 433499Sbostic * 533499Sbostic * Redistribution and use in source and binary forms are permitted 633499Sbostic * provided that this notice is preserved and that due credit is given 733499Sbostic * to the University of California at Berkeley. The name of the University 833499Sbostic * may not be used to endorse or promote products derived from this 933499Sbostic * software without specific prior written permission. This software 1033499Sbostic * is provided ``as is'' without express or implied warranty. 1122451Sdist */ 1222451Sdist 1333499Sbostic #ifdef notdef 14*34879Sedward static char sccsid[] = "@(#)edit.c 5.6 (Berkeley) 06/29/88"; 1533499Sbostic #endif /* notdef */ 161228Skas 171228Skas #include "rcv.h" 181228Skas #include <stdio.h> 191228Skas #include <sys/stat.h> 2031142Sedward #include <sys/wait.h> 211228Skas 221228Skas /* 231228Skas * Mail -- a mail program 241228Skas * 251228Skas * Perform message editing functions. 261228Skas */ 271228Skas 281228Skas /* 291228Skas * Edit a message list. 301228Skas */ 311228Skas 321228Skas editor(msgvec) 331228Skas int *msgvec; 341228Skas { 351228Skas char *edname; 361228Skas 371228Skas if ((edname = value("EDITOR")) == NOSTR) 381228Skas edname = EDITOR; 391228Skas return(edit1(msgvec, edname)); 401228Skas } 411228Skas 421228Skas /* 431228Skas * Invoke the visual editor on a message list. 441228Skas */ 451228Skas 461228Skas visual(msgvec) 471228Skas int *msgvec; 481228Skas { 491228Skas char *edname; 501228Skas 511228Skas if ((edname = value("VISUAL")) == NOSTR) 521228Skas edname = VISUAL; 531228Skas return(edit1(msgvec, edname)); 541228Skas } 551228Skas 561228Skas /* 571228Skas * Edit a message by writing the message into a funnily-named file 581228Skas * (which should not exist) and forking an editor on it. 591228Skas * We get the editor from the stuff above. 601228Skas */ 611228Skas edit1(msgvec, ed) 621228Skas int *msgvec; 631228Skas char *ed; 641228Skas { 651228Skas register int c; 66*34879Sedward int i, pid; 671228Skas int (*sigint)(), (*sigquit)(); 68*34879Sedward FILE *fp; 69*34879Sedward extern char tempEdit[]; 70*34879Sedward char *edname = tempEdit; 7131142Sedward register struct message *mp; 721228Skas off_t fsize(), size; 731228Skas struct stat statb; 74*34879Sedward time_t modtime; 7531142Sedward union wait status; 761228Skas 771228Skas /* 781228Skas * Set signals; locate editor. 791228Skas */ 8031142Sedward sigint = signal(SIGINT, SIG_IGN); 8131142Sedward sigquit = signal(SIGQUIT, SIG_IGN); 821228Skas /* 831228Skas * Deal with each message to be edited . . . 841228Skas */ 85*34879Sedward for (i = 0; msgvec[i] && i < msgCount; i++) { 86*34879Sedward mp = &message[msgvec[i] - 1]; 871228Skas mp->m_flag |= MODIFY; 88*34879Sedward touch(msgvec[i]); 8931142Sedward dot = mp; 901228Skas /* 91*34879Sedward * Copy the message into the edit file. 92*34879Sedward * If we are in read only mode, make the 93*34879Sedward * temporary message file readonly as well. 941228Skas */ 95*34879Sedward if ((c = creat(edname, readonly ? 0400 : 0600)) < 0) { 96*34879Sedward perror(edname); 971228Skas goto out; 981228Skas } 99*34879Sedward if ((fp = fdopen(c, "w")) == NULL) { 1001228Skas perror(edname); 101*34879Sedward (void) unlink(edname); 1021228Skas goto out; 1031228Skas } 104*34879Sedward if (send(mp, fp, 0) < 0) { 1051228Skas perror(edname); 106*34879Sedward (void) fclose(fp); 107*34879Sedward (void) unlink(edname); 1081228Skas goto out; 1091228Skas } 110*34879Sedward (void) fflush(fp); 111*34879Sedward if (ferror(fp)) { 112*34879Sedward (void) unlink(edname); 113*34879Sedward (void) fclose(fp); 1141228Skas goto out; 1151228Skas } 116*34879Sedward if (fstat(fileno(fp), &statb) < 0) 117*34879Sedward modtime = 0; 118*34879Sedward else 119*34879Sedward modtime = statb.st_mtime; 120*34879Sedward (void) fclose(fp); 1211228Skas /* 1221228Skas * Fork/execl the editor on the edit file. 1231228Skas */ 1241228Skas pid = vfork(); 1251228Skas if (pid == -1) { 1261228Skas perror("fork"); 127*34879Sedward (void) unlink(edname); 1281228Skas goto out; 1291228Skas } 1301228Skas if (pid == 0) { 1311228Skas if (sigint != SIG_IGN) 13231143Sedward (void) signal(SIGINT, SIG_DFL); 1331228Skas if (sigquit != SIG_IGN) 13431143Sedward (void) signal(SIGQUIT, SIG_DFL); 1351228Skas execl(ed, ed, edname, 0); 1361228Skas perror(ed); 1371228Skas _exit(1); 1381228Skas } 13931142Sedward while (wait(&status) != pid) 1401228Skas ; 1411228Skas /* 1421472Skas * If in read only mode, just remove the editor 1431472Skas * temporary and return. 1441472Skas */ 1451472Skas if (readonly) { 146*34879Sedward (void) unlink(edname); 1471472Skas continue; 1481472Skas } 1491472Skas /* 1501228Skas * Now copy the message to the end of the 1511228Skas * temp file. 1521228Skas */ 1531228Skas if (stat(edname, &statb) < 0) { 1541228Skas perror(edname); 1551228Skas goto out; 1561228Skas } 1571228Skas if (modtime == statb.st_mtime) { 158*34879Sedward (void) unlink(edname); 1591228Skas goto out; 1601228Skas } 161*34879Sedward if ((fp = fopen(edname, "r")) == NULL) { 1621228Skas perror(edname); 163*34879Sedward (void) unlink(edname); 1641228Skas goto out; 1651228Skas } 166*34879Sedward (void) unlink(edname); 16731143Sedward (void) fseek(otf, (long) 0, 2); 16831142Sedward size = ftell(otf); 1691228Skas mp->m_block = blockof(size); 1701228Skas mp->m_offset = offsetof(size); 171*34879Sedward mp->m_size = fsize(fp); 17231142Sedward mp->m_lines = 0; 173*34879Sedward while ((c = getc(fp)) != EOF) { 1741228Skas if (c == '\n') 17531142Sedward mp->m_lines++; 17631143Sedward (void) putc(c, otf); 1771228Skas if (ferror(otf)) 1781228Skas break; 1791228Skas } 1801228Skas if (ferror(otf)) 1811228Skas perror("/tmp"); 182*34879Sedward (void) fclose(fp); 1831228Skas } 1841228Skas /* 1851228Skas * Restore signals and return. 1861228Skas */ 1871228Skas out: 18831143Sedward (void) signal(SIGINT, sigint); 18931143Sedward (void) signal(SIGQUIT, sigquit); 19031142Sedward return 0; 1911228Skas } 192