Bug Summary

File:src/usr.bin/mail/quit.c
Warning:line 266, column 8
Access to field '_r' results in a dereference of a null pointer (loaded from variable 'ibuf')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name quit.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/mail/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/mail/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/mail/quit.c
1/* $OpenBSD: quit.c,v 1.23 2016/07/19 06:43:27 deraadt Exp $ */
2/* $NetBSD: quit.c,v 1.6 1996/12/28 07:11:07 tls Exp $ */
3
4/*
5 * Copyright (c) 1980, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include "rcv.h"
34#include <fcntl.h>
35#include "extern.h"
36
37/*
38 * Rcv -- receive mail rationally.
39 *
40 * Termination processing.
41 */
42
43/*
44 * The "quit" command.
45 */
46int
47quitcmd(void *v)
48{
49 /*
50 * If we are sourcing, then return 1 so execute() can handle it.
51 * Otherwise, return -1 to abort command loop.
52 */
53 if (sourcing)
54 return(1);
55 return(-1);
56}
57
58/*
59 * Save all of the undetermined messages at the top of "mbox"
60 * Save all untouched messages back in the system mailbox.
61 * Remove the system mailbox, if none saved there.
62 */
63int
64quit(void)
65{
66 int mcount, p, modify, autohold, anystat, holdbit, nohold;
67 FILE *ibuf = NULL((void *)0), *obuf, *fbuf, *rbuf, *abuf;
1
'ibuf' initialized to a null pointer value
68 struct message *mp;
69 int c, fd;
70 struct stat minfo;
71 char *mbox, tempname[PATHSIZE1024];
72
73 /*
74 * If we are read only, we can't do anything,
75 * so just return quickly.
76 */
77 if (readonly)
2
Assuming 'readonly' is 0
3
Taking false branch
78 return(0);
79
80 /*
81 * If editing (not reading system mail box), then do the work
82 * in edstop()
83 */
84 if (edit)
4
Assuming 'edit' is 0
5
Taking false branch
85 return(edstop());
86
87 /*
88 * See if there any messages to save in mbox. If no, we
89 * can save copying mbox to /tmp and back.
90 *
91 * Check also to see if any files need to be preserved.
92 * Delete all untouched messages to keep them out of mbox.
93 * If all the messages are to be preserved, just exit with
94 * a message.
95 */
96 fbuf = Fopen(mailname, "r+");
97 if (fbuf == NULL((void *)0))
6
Assuming 'fbuf' is not equal to NULL
7
Taking false branch
98 goto newmail;
99 if (flock(fileno(fbuf)(!__isthreaded ? ((fbuf)->_file) : (fileno)(fbuf)), LOCK_EX0x02) == -1) {
8
Assuming '__isthreaded' is 0
9
'?' condition is true
10
Assuming the condition is false
11
Taking false branch
100 warn("Unable to lock mailbox");
101 (void)Fclose(fbuf);
102 return(-1);
103 }
104 if (!spool_lock()) {
12
Assuming the condition is false
13
Taking false branch
105 (void)Fclose(fbuf);
106 return(-1); /* lockspool printed the error for us */
107 }
108 rbuf = NULL((void *)0);
109 if (fstat(fileno(fbuf)(!__isthreaded ? ((fbuf)->_file) : (fileno)(fbuf)), &minfo) >= 0 && minfo.st_size > mailsize) {
14
Assuming '__isthreaded' is not equal to 0
15
'?' condition is false
16
Assuming the condition is false
110 puts("New mail has arrived.");
111 (void)snprintf(tempname, sizeof(tempname),
112 "%s/mail.RqXXXXXXXXXX", tmpdir);
113 if ((fd = mkstemp(tempname)) == -1 ||
114 (rbuf = Fdopen(fd, "w")) == NULL((void *)0))
115 goto newmail;
116#ifdef APPEND
117 fseek(fbuf, (long)mailsize, SEEK_SET0);
118 while ((c = getc(fbuf)(!__isthreaded ? (--(fbuf)->_r < 0 ? __srget(fbuf) : (int
)(*(fbuf)->_p++)) : (getc)(fbuf))
) != EOF(-1))
119 (void)putc(c, rbuf)(!__isthreaded ? __sputc(c, rbuf) : (putc)(c, rbuf));
120#else
121 p = minfo.st_size - mailsize;
122 while (p-- > 0) {
123 c = getc(fbuf)(!__isthreaded ? (--(fbuf)->_r < 0 ? __srget(fbuf) : (int
)(*(fbuf)->_p++)) : (getc)(fbuf))
;
124 if (c == EOF(-1))
125 goto newmail;
126 (void)putc(c, rbuf)(!__isthreaded ? __sputc(c, rbuf) : (putc)(c, rbuf));
127 }
128#endif
129 (void)Fclose(rbuf);
130 if ((rbuf = Fopen(tempname, "r")) == NULL((void *)0))
131 goto newmail;
132 (void)rm(tempname);
133 }
134
135 /*
136 * Adjust the message flags in each message.
137 */
138 anystat = 0;
139 autohold = value("hold") != NULL((void *)0);
17
Assuming the condition is false
140 holdbit = autohold
17.1
'autohold' is 0
? MPRESERVE(1<<4) : MBOX(1<<10);
18
'?' condition is false
141 nohold = MBOX(1<<10)|MSAVED(1<<2)|MDELETED(1<<1)|MPRESERVE(1<<4);
142 if (value("keepsave") != NULL((void *)0))
19
Assuming the condition is false
20
Taking false branch
143 nohold &= ~MSAVED(1<<2);
144 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
21
Loop condition is false. Execution continues on line 156
145 if (mp->m_flag & MNEW(1<<7)) {
146 mp->m_flag &= ~MNEW(1<<7);
147 mp->m_flag |= MSTATUS(1<<9);
148 }
149 if (mp->m_flag & MSTATUS(1<<9))
150 anystat++;
151 if ((mp->m_flag & MTOUCH(1<<3)) == 0)
152 mp->m_flag |= MPRESERVE(1<<4);
153 if ((mp->m_flag & nohold) == 0)
154 mp->m_flag |= holdbit;
155 }
156 modify = 0;
157 for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
22
Loop condition is true. Entering loop body
29
Assuming the condition is false
158 if (mp->m_flag & MBOX(1<<10))
23
Assuming the condition is true
24
Taking true branch
159 c++;
160 if (mp->m_flag & MPRESERVE(1<<4))
25
Assuming the condition is false
26
Taking false branch
161 p++;
162 if (mp->m_flag & MODIFY(1<<6))
27
Assuming the condition is false
28
Taking false branch
163 modify++;
164 }
165 if (p == msgCount && !modify && !anystat) {
30
Assuming 'p' is not equal to 'msgCount'
166 printf("Held %d message%s in %s\n",
167 p, p == 1 ? "" : "s", mailname);
168 (void)Fclose(fbuf);
169 spool_unlock();
170 return(0);
171 }
172 if (c
30.1
'c' is not equal to 0
== 0) {
31
Taking false branch
173 if (p != 0) {
174 writeback(rbuf);
175 (void)Fclose(fbuf);
176 spool_unlock();
177 return(0);
178 }
179 goto cream;
180 }
181
182 /*
183 * Create another temporary file and copy user's mbox file
184 * darin. If there is no mbox, copy nothing.
185 * If he has specified "append" don't copy his mailbox,
186 * just copy saveable entries at the end.
187 */
188 mbox = expand("&");
189 mcount = c;
190 if (value("append") == NULL((void *)0)) {
32
Assuming the condition is false
33
Taking false branch
191 int fdx;
192
193 (void)snprintf(tempname, sizeof(tempname),
194 "%s/mail.RmXXXXXXXXXX", tmpdir);
195 if ((fd = mkstemp(tempname)) == -1 ||
196 (obuf = Fdopen(fd, "w")) == NULL((void *)0)) {
197 warn("%s", tempname);
198 (void)Fclose(fbuf);
199 spool_unlock();
200 return(-1);
201 }
202 if ((ibuf = Fopen(tempname, "r")) == NULL((void *)0)) {
203 warn("%s", tempname);
204 (void)rm(tempname);
205 (void)Fclose(obuf);
206 (void)Fclose(fbuf);
207 spool_unlock();
208 return(-1);
209 }
210 (void)rm(tempname);
211 if ((abuf = Fopen(mbox, "r")) != NULL((void *)0)) {
212 while ((c = getc(abuf)(!__isthreaded ? (--(abuf)->_r < 0 ? __srget(abuf) : (int
)(*(abuf)->_p++)) : (getc)(abuf))
) != EOF(-1))
213 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
214 (void)Fclose(abuf);
215 }
216 if (ferror(obuf)(!__isthreaded ? (((obuf)->_flags & 0x0040) != 0) : (ferror
)(obuf))
) {
217 warn("%s", tempname);
218 (void)Fclose(ibuf);
219 (void)Fclose(obuf);
220 (void)Fclose(fbuf);
221 spool_unlock();
222 return(-1);
223 }
224 (void)Fclose(obuf);
225 if ((fdx = open(mbox, O_CREAT0x0200 | O_TRUNC0x0400 | O_WRONLY0x0001, 0600)) != -1)
226 close(fdx);
227 if ((obuf = Fopen(mbox, "r+")) == NULL((void *)0)) {
228 warn("%s", mbox);
229 (void)Fclose(ibuf);
230 (void)Fclose(fbuf);
231 spool_unlock();
232 return(-1);
233 }
234 } else {
235 if ((obuf = Fopen(mbox, "a")) == NULL((void *)0)) {
34
Assuming the condition is false
35
Taking false branch
236 warn("%s", mbox);
237 (void)Fclose(fbuf);
238 spool_unlock();
239 return(-1);
240 }
241 fchmod(fileno(obuf)(!__isthreaded ? ((obuf)->_file) : (fileno)(obuf)), 0600);
36
Assuming '__isthreaded' is 0
37
'?' condition is true
242 }
243 for (mp = &message[0]; mp < &message[msgCount]; mp++)
38
Loop condition is false. Execution continues on line 259
244 if (mp->m_flag & MBOX(1<<10))
245 if (sendmessage(mp, obuf, saveignore, NULL((void *)0)) < 0) {
246 warn("%s", mbox);
247 (void)Fclose(ibuf);
248 (void)Fclose(obuf);
249 (void)Fclose(fbuf);
250 spool_unlock();
251 return(-1);
252 }
253
254 /*
255 * Copy the user's old mbox contents back
256 * to the end of the stuff we just saved.
257 * If we are appending, this is unnecessary.
258 */
259 if (value("append") == NULL((void *)0)) {
39
Assuming the condition is true
40
Taking true branch
260 rewind(ibuf);
261 c = getc(ibuf)(!__isthreaded ? (--(ibuf)->_r < 0 ? __srget(ibuf) : (int
)(*(ibuf)->_p++)) : (getc)(ibuf))
;
41
Assuming '__isthreaded' is not equal to 0
42
'?' condition is false
262 while (c != EOF(-1)) {
43
Assuming the condition is true
44
Loop condition is true. Entering loop body
263 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
45
Assuming '__isthreaded' is not equal to 0
46
'?' condition is false
264 if (ferror(obuf)(!__isthreaded ? (((obuf)->_flags & 0x0040) != 0) : (ferror
)(obuf))
)
47
Assuming '__isthreaded' is 0
48
'?' condition is true
49
Assuming the condition is false
265 break;
266 c = getc(ibuf)(!__isthreaded ? (--(ibuf)->_r < 0 ? __srget(ibuf) : (int
)(*(ibuf)->_p++)) : (getc)(ibuf))
;
50
Taking false branch
51
'?' condition is true
52
Access to field '_r' results in a dereference of a null pointer (loaded from variable 'ibuf')
267 }
268 (void)Fclose(ibuf);
269 fflush(obuf);
270 }
271 trunc(obuf)do { (void)fflush(obuf); (void)ftruncate((!__isthreaded ? ((obuf
)->_file) : (fileno)(obuf)), (off_t)ftell(obuf)); } while(
0)
;
272 if (ferror(obuf)(!__isthreaded ? (((obuf)->_flags & 0x0040) != 0) : (ferror
)(obuf))
) {
273 warn("%s", mbox);
274 (void)Fclose(obuf);
275 (void)Fclose(fbuf);
276 spool_unlock();
277 return(-1);
278 }
279 (void)Fclose(obuf);
280 if (mcount == 1)
281 puts("Saved 1 message in mbox");
282 else
283 printf("Saved %d messages in mbox\n", mcount);
284
285 /*
286 * Now we are ready to copy back preserved files to
287 * the system mailbox, if any were requested.
288 */
289 if (p != 0) {
290 writeback(rbuf);
291 (void)Fclose(fbuf);
292 spool_unlock();
293 return(0);
294 }
295
296 /*
297 * Finally, remove his /var/mail file.
298 * If new mail has arrived, copy it back.
299 */
300cream:
301 if (rbuf != NULL((void *)0)) {
302 abuf = Fopen(mailname, "r+");
303 if (abuf == NULL((void *)0))
304 goto newmail;
305 while ((c = getc(rbuf)(!__isthreaded ? (--(rbuf)->_r < 0 ? __srget(rbuf) : (int
)(*(rbuf)->_p++)) : (getc)(rbuf))
) != EOF(-1))
306 (void)putc(c, abuf)(!__isthreaded ? __sputc(c, abuf) : (putc)(c, abuf));
307 (void)Fclose(rbuf);
308 trunc(abuf)do { (void)fflush(abuf); (void)ftruncate((!__isthreaded ? ((abuf
)->_file) : (fileno)(abuf)), (off_t)ftell(abuf)); } while(
0)
;
309 (void)Fclose(abuf);
310 alter(mailname);
311 (void)Fclose(fbuf);
312 spool_unlock();
313 return(0);
314 }
315 demail();
316 (void)Fclose(fbuf);
317 spool_unlock();
318 return(0);
319
320newmail:
321 puts("Thou hast new mail.");
322 if (fbuf != NULL((void *)0)) {
323 (void)Fclose(fbuf);
324 spool_unlock();
325 }
326 return(0);
327}
328
329/*
330 * Preserve all the appropriate messages back in the system
331 * mailbox, and print a nice message indicated how many were
332 * saved. On any error, just return -1. Else return 0.
333 * Incorporate the any new mail that we found.
334 */
335int
336writeback(FILE *res)
337{
338 struct message *mp;
339 int p, c;
340 FILE *obuf;
341
342 p = 0;
343 if ((obuf = Fopen(mailname, "r+")) == NULL((void *)0)) {
344 warn("%s", mailname);
345 return(-1);
346 }
347#ifndef APPEND
348 if (res != NULL((void *)0))
349 while ((c = getc(res)(!__isthreaded ? (--(res)->_r < 0 ? __srget(res) : (int
)(*(res)->_p++)) : (getc)(res))
) != EOF(-1))
350 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
351#endif
352 for (mp = &message[0]; mp < &message[msgCount]; mp++)
353 if ((mp->m_flag&MPRESERVE(1<<4))||(mp->m_flag&MTOUCH(1<<3))==0) {
354 p++;
355 if (sendmessage(mp, obuf, NULL((void *)0), NULL((void *)0)) < 0) {
356 warn("%s", mailname);
357 (void)Fclose(obuf);
358 return(-1);
359 }
360 }
361#ifdef APPEND
362 if (res != NULL((void *)0))
363 while ((c = getc(res)(!__isthreaded ? (--(res)->_r < 0 ? __srget(res) : (int
)(*(res)->_p++)) : (getc)(res))
) != EOF(-1))
364 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
365#endif
366 fflush(obuf);
367 trunc(obuf)do { (void)fflush(obuf); (void)ftruncate((!__isthreaded ? ((obuf
)->_file) : (fileno)(obuf)), (off_t)ftell(obuf)); } while(
0)
;
368 if (ferror(obuf)(!__isthreaded ? (((obuf)->_flags & 0x0040) != 0) : (ferror
)(obuf))
) {
369 warn("%s", mailname);
370 (void)Fclose(obuf);
371 return(-1);
372 }
373 if (res != NULL((void *)0))
374 (void)Fclose(res);
375 (void)Fclose(obuf);
376 alter(mailname);
377 if (p == 1)
378 printf("Held 1 message in %s\n", mailname);
379 else
380 printf("Held %d messages in %s\n", p, mailname);
381 return(0);
382}
383
384/*
385 * Terminate an editing session by attempting to write out the user's
386 * file from the temporary. Save any new stuff appended to the file.
387 */
388int
389edstop(void)
390{
391 int gotcha, c;
392 struct message *mp;
393 FILE *obuf, *ibuf;
394 struct stat statb;
395 char tempname[PATHSIZE1024];
396
397 if (readonly)
398 return(0);
399 holdsigs();
400 for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
401 if (mp->m_flag & MNEW(1<<7)) {
402 mp->m_flag &= ~MNEW(1<<7);
403 mp->m_flag |= MSTATUS(1<<9);
404 }
405 if (mp->m_flag & (MODIFY(1<<6)|MDELETED(1<<1)|MSTATUS(1<<9)))
406 gotcha++;
407 }
408 if (!gotcha)
409 goto done;
410 ibuf = NULL((void *)0);
411 if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
412 int fd;
413
414 (void)snprintf(tempname, sizeof(tempname), "%s/mbox.XXXXXXXXXX",
415 tmpdir);
416 if ((fd = mkstemp(tempname)) == -1 ||
417 (obuf = Fdopen(fd, "w")) == NULL((void *)0)) {
418 warn("%s", tempname);
419 if (fd != -1)
420 close(fd);
421 relsesigs();
422 return(-1);
423 }
424 if ((ibuf = Fopen(mailname, "r")) == NULL((void *)0)) {
425 warn("%s", mailname);
426 (void)Fclose(obuf);
427 (void)rm(tempname);
428 relsesigs();
429 return(-1);
430 }
431 fseek(ibuf, (long)mailsize, SEEK_SET0);
432 while ((c = getc(ibuf)(!__isthreaded ? (--(ibuf)->_r < 0 ? __srget(ibuf) : (int
)(*(ibuf)->_p++)) : (getc)(ibuf))
) != EOF(-1))
433 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
434 (void)Fclose(ibuf);
435 (void)Fclose(obuf);
436 if ((ibuf = Fopen(tempname, "r")) == NULL((void *)0)) {
437 warn("%s", tempname);
438 (void)rm(tempname);
439 relsesigs();
440 return(-1);
441 }
442 (void)rm(tempname);
443 }
444 printf("\"%s\" ", mailname);
445 fflush(stdout(&__sF[1]));
446 if ((obuf = Fopen(mailname, "r+")) == NULL((void *)0)) {
447 warn("%s", mailname);
448 relsesigs();
449 return(-1);
450 }
451 trunc(obuf)do { (void)fflush(obuf); (void)ftruncate((!__isthreaded ? ((obuf
)->_file) : (fileno)(obuf)), (off_t)ftell(obuf)); } while(
0)
;
452 c = 0;
453 for (mp = &message[0]; mp < &message[msgCount]; mp++) {
454 if ((mp->m_flag & MDELETED(1<<1)) != 0)
455 continue;
456 c++;
457 if (sendmessage(mp, obuf, NULL((void *)0), NULL((void *)0)) < 0) {
458 warn("%s", mailname);
459 relsesigs();
460 return(-1);
461 }
462 }
463 gotcha = (c == 0 && ibuf == NULL((void *)0));
464 if (ibuf != NULL((void *)0)) {
465 while ((c = getc(ibuf)(!__isthreaded ? (--(ibuf)->_r < 0 ? __srget(ibuf) : (int
)(*(ibuf)->_p++)) : (getc)(ibuf))
) != EOF(-1))
466 (void)putc(c, obuf)(!__isthreaded ? __sputc(c, obuf) : (putc)(c, obuf));
467 (void)Fclose(ibuf);
468 }
469 fflush(obuf);
470 if (ferror(obuf)(!__isthreaded ? (((obuf)->_flags & 0x0040) != 0) : (ferror
)(obuf))
) {
471 warn("%s", mailname);
472 relsesigs();
473 return(-1);
474 }
475 (void)Fclose(obuf);
476 if (gotcha) {
477 (void)rm(mailname);
478 puts("removed");
479 } else
480 puts("complete");
481 fflush(stdout(&__sF[1]));
482
483done:
484 relsesigs();
485 return(0);
486}