1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 /* 26 * NAME 27 * copyback - copy temp or whatever back to /var/mail 28 * 29 * SYNOPSIS 30 * void copyback() 31 * 32 * DESCRIPTION 33 * Copy the reduced contents of lettmp back to 34 * the mail file. First copy any new mail from 35 * the mail file to the end of lettmp. 36 */ 37 38 #include "mail.h" 39 void 40 copyback() 41 { 42 register int i, n; 43 int new = 0; 44 mode_t mailmode, omask; 45 struct stat stbuf; 46 void (*hstat)(), (*istat)(), (*qstat)(); 47 48 istat = signal(SIGINT, SIG_IGN); 49 qstat = signal(SIGQUIT, SIG_IGN); 50 hstat = signal(SIGHUP, SIG_IGN); 51 lock(my_name); 52 stat(mailfile, &stbuf); 53 mailmode = stbuf.st_mode; 54 55 /* 56 * Has new mail arrived? 57 */ 58 if (stbuf.st_size != let[nlet].adr) { 59 malf = doopen(mailfile, "r", E_FILE); 60 fseek(malf, let[nlet].adr, 0); 61 fclose(tmpf); 62 tmpf = doopen(lettmp, "a", E_TMP); 63 /* 64 * Append new mail assume only one new letter 65 */ 66 if (!copystream(malf, tmpf)) { 67 fclose(malf); 68 tmperr(); 69 done(0); 70 } 71 fclose(malf); 72 fclose(tmpf); 73 tmpf = doopen(lettmp, "r+", E_TMP); 74 if (nlet == (MAXLET-2)) { 75 errmsg(E_SPACE, ""); 76 done(0); 77 } 78 let[++nlet].adr = stbuf.st_size; 79 new = 1; 80 } 81 82 /* 83 * Copy mail back to mail file 84 */ 85 omask = umask(0117); 86 87 /* 88 * The invoker must own the mailfile being copied to 89 */ 90 if ((stbuf.st_uid != my_euid) && (stbuf.st_uid != my_uid)) { 91 errmsg(E_OWNR, ""); 92 done(0); 93 } 94 95 /* 96 * If user specified the '-f' option we dont do 97 * the routines to handle :saved files. 98 * As we would(incorrectly) restore to the user's 99 * mailfile upon next execution! 100 */ 101 if (flgf) { 102 (void) strlcpy(savefile, mailfile, sizeof (savefile)); 103 } else { 104 cat(savefile, mailsave, my_name); 105 } 106 107 if ((malf = fopen(savefile, "w")) == NULL) { 108 if (!flgf) { 109 errmsg(E_FILE, "Cannot open savefile"); 110 } else { 111 errmsg(E_FILE, "Cannot re-write the alternate file"); 112 } 113 done(0); 114 } 115 116 if (chown(savefile, mf_uid, mf_gid) == -1) { 117 errmsg(E_FILE, "Cannot chown savefile"); 118 done(0); 119 } 120 umask(omask); 121 n = 0; 122 123 for (i = 0; i < nlet; i++) { 124 /* 125 * Note: any action other than an undelete, or a 126 * plain read causes the letter acted upon to be 127 * deleted 128 */ 129 if (let[i].change == ' ') { 130 if (copylet(i, malf, ORDINARY) == FALSE) { 131 errmsg(E_FILE, "Cannot copy mail to savefile"); 132 (void) fprintf(stderr, "%s: A copy of your " 133 "mailfile is in '%s'\n", program, lettmp); 134 done(1); /* keep temp file */ 135 } 136 n++; 137 } 138 } 139 fclose(malf); 140 141 if (!flgf) { 142 if (unlink(mailfile) != 0) { 143 errmsg(E_FILE, "Cannot unlink mailfile"); 144 done(0); 145 } 146 chmod(savefile, mailmode); 147 #ifdef SVR4 148 if (rename(savefile, mailfile) != 0) { 149 errmsg(E_FILE, "Cannot rename savefile to mailfile"); 150 done(0); 151 } 152 #else 153 if (link(savefile, mailfile) != 0) { 154 errmsg(E_FILE, "Cannot link savefile to mailfile"); 155 done(0); 156 } 157 if (unlink(savefile) != 0) { 158 errmsg(E_FILE, "Cannot unlink save file"); 159 done(0); 160 } 161 #endif 162 } 163 164 /* 165 * Empty mailbox? 166 */ 167 if (n == 0) { 168 delempty(stbuf.st_mode, mailfile); 169 } 170 171 if (new && !flgf) { 172 printf("New mail arrived\n"); 173 } 174 175 unlock(); 176 (void) signal(SIGINT, istat); 177 (void) signal(SIGQUIT, qstat); 178 (void) signal(SIGHUP, hstat); 179 } 180