Bug Summary

File:src/sbin/shutdown/shutdown.c
Warning:line 370, column 10
Although the value stored to 'wpid' is used in the enclosing expression, the value is never actually read from 'wpid'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name shutdown.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fno-rounding-math -mconstructor-aliases -munwind-tables -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/sbin/shutdown/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/shutdown/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -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/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/shutdown/shutdown.c
1/* $OpenBSD: shutdown.c,v 1.53 2021/07/12 15:09:19 beck Exp $ */
2/* $NetBSD: shutdown.c,v 1.9 1995/03/18 15:01:09 cgd Exp $ */
3
4/*
5 * Copyright (c) 1988, 1990, 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 <sys/types.h>
34#include <sys/resource.h>
35#include <sys/syslog.h>
36#include <sys/types.h>
37#include <sys/wait.h>
38
39#include <ctype.h>
40#include <fcntl.h>
41#include <sys/termios.h>
42#include <pwd.h>
43#include <signal.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <time.h>
48#include <unistd.h>
49#include <limits.h>
50#include <errno(*__errno()).h>
51#include <err.h>
52
53#include "pathnames.h"
54
55#ifdef DEBUG
56#undef _PATH_NOLOGIN"/etc/nologin"
57#define _PATH_NOLOGIN"/etc/nologin" "./nologin"
58#undef _PATH_FASTBOOT"/fastboot"
59#define _PATH_FASTBOOT"/fastboot" "./fastboot"
60#endif
61
62#define H *60*60LL
63#define M *60LL
64#define S *1LL
65#define TEN_HOURS(10*60*60) (10*60*60)
66#define NOLOG_TIME(5*60) (5*60)
67struct interval {
68 time_t timeleft;
69 time_t timetowait;
70} tlist[] = {
71 { 0, 0 },
72 { 10 H, 5 H },
73 { 5 H, 3 H },
74 { 2 H, 1 H },
75 { 1 H, 30 M },
76 { 30 M, 10 M },
77 { 20 M, 10 M },
78 { 10 M, 5 M },
79 { 5 M, 3 M },
80 { 2 M, 1 M },
81 { 1 M, 30 S },
82 { 30 S, 30 S },
83 { 0, 0 }
84};
85const int tlistlen = sizeof(tlist) / sizeof(tlist[0]);
86#undef H
87#undef M
88#undef S
89
90static time_t offset, shuttime;
91static int dofast, dohalt, doreboot, dopower, dodump, mbuflen, nosync;
92static sig_atomic_t killflg, timed_out;
93static char *whom, mbuf[BUFSIZ1024];
94
95void badtime(void);
96void __dead__attribute__((__noreturn__)) die_you_gravy_sucking_pig_dog(void);
97void doitfast(void);
98void __dead__attribute__((__noreturn__)) finish(int);
99void getoffset(char *);
100void __dead__attribute__((__noreturn__)) loop(void);
101void nolog(time_t);
102void timeout(int);
103void timewarn(time_t);
104void usage(void);
105
106int
107main(int argc, char *argv[])
108{
109 char when[64];
110 char *p, *endp;
111 struct passwd *pw;
112 struct tm *lt;
113 int arglen, ch, len, readstdin = 0;
114 pid_t forkpid;
115
116#ifndef DEBUG
117 if (geteuid())
118 errx(1, "NOT super-user");
119#endif
120 while ((ch = getopt(argc, argv, "dfhknpr-")) != -1)
121 switch (ch) {
122 case '-':
123 readstdin = 1;
124 break;
125 case 'd':
126 dodump = 1;
127 break;
128 case 'f':
129 dofast = 1;
130 break;
131 case 'h':
132 dohalt = 1;
133 break;
134 case 'k':
135 killflg = 1;
136 break;
137 case 'n':
138 nosync = 1;
139 break;
140 case 'p':
141 dopower = 1;
142 break;
143 case 'r':
144 doreboot = 1;
145 break;
146 default:
147 usage();
148 }
149 argc -= optind;
150 argv += optind;
151
152 if (argc < 1)
153 usage();
154
155 if (dofast && nosync) {
156 warnx("incompatible switches -f and -n.");
157 usage();
158 }
159 if (doreboot && dohalt) {
160 warnx("incompatible switches -h and -r.");
161 usage();
162 }
163 if (doreboot && dopower) {
164 warnx("incompatible switches -p and -r.");
165 usage();
166 }
167
168 if (unveil(_PATH_CONSOLE"/dev/console", "rw") == -1)
169 err(1, "unveil %s", _PATH_CONSOLE"/dev/console");
170 if (unveil(_PATH_RC"/etc/rc", "r") == -1)
171 err(1, "unveil %s", _PATH_RC"/etc/rc");
172 if (unveil(_PATH_WALL"/usr/bin/wall", "x") == -1)
173 err(1, "unveil %s", _PATH_WALL"/usr/bin/wall");
174 if (unveil(_PATH_FASTBOOT"/fastboot", "wc") == -1)
175 err(1, "unveil %s", _PATH_FASTBOOT"/fastboot");
176 if (unveil(_PATH_NOLOGIN"/etc/nologin", "wc") == -1)
177 err(1, "unveil %s", _PATH_NOLOGIN"/etc/nologin");
178 if (dohalt || dopower) {
179 if (unveil(_PATH_HALT"/sbin/halt", "x") == -1)
180 err(1, "unveil %s", _PATH_HALT"/sbin/halt");
181 } else if (doreboot) {
182 if (unveil(_PATH_REBOOT"/sbin/reboot", "x") == -1)
183 err(1, "unveil %s", _PATH_REBOOT"/sbin/reboot");
184 } else {
185 if (unveil(_PATH_BSHELL"/bin/sh", "x") == -1)
186 err(1, "unveil %s", _PATH_BSHELL"/bin/sh");
187 }
188 if (pledge("stdio rpath wpath cpath getpw tty id proc exec", NULL((void *)0)) == -1)
189 err(1, "pledge");
190
191 getoffset(*argv++);
192
193 if (*argv) {
194 for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) {
195 arglen = strlen(*argv);
196 if ((len -= arglen) <= 2)
197 break;
198 if (p != mbuf)
199 *p++ = ' ';
200 memcpy(p, *argv, arglen);
201 p += arglen;
202 }
203 *p = '\n';
204 *++p = '\0';
205 }
206
207 if (readstdin) {
208 p = mbuf;
209 endp = mbuf + sizeof(mbuf) - 2;
210 for (;;) {
211 if (!fgets(p, endp - p + 1, stdin(&__sF[0])))
212 break;
213 for (; *p && p < endp; ++p)
214 ;
215 if (p == endp) {
216 *p = '\n';
217 *++p = '\0';
218 break;
219 }
220 }
221 }
222 mbuflen = strlen(mbuf);
223
224 if (offset > 0) {
225 shuttime = time(NULL((void *)0)) + offset;
226 lt = localtime(&shuttime);
227 if (lt != NULL((void *)0)) {
228 strftime(when, sizeof(when), "%a %b %e %T %Z %Y", lt);
229 printf("Shutdown at %s.\n", when);
230 } else
231 printf("Shutdown soon.\n");
232 } else
233 printf("Shutdown NOW!\n");
234
235 if (!(whom = getlogin()))
236 whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
237
238#ifdef DEBUG
239 (void)putc('\n', stdout)(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
240#else
241 (void)setpriority(PRIO_PROCESS0, 0, PRIO_MIN(-20));
242
243 forkpid = fork();
244 if (forkpid == -1)
245 err(1, "fork");
246 if (forkpid) {
247 (void)printf("shutdown: [pid %ld]\n", (long)forkpid);
248 exit(0);
249 }
250 setsid();
251#endif
252 openlog("shutdown", LOG_CONS0x02, LOG_AUTH(4<<3));
253 loop();
254 /* NOTREACHED */
255}
256
257void
258loop(void)
259{
260 struct timespec timeout;
261 int broadcast, i, logged;
262
263 broadcast = 1;
264
265 for (i = 0; i < tlistlen - 1; i++) {
266 if (offset > tlist[i + 1].timeleft) {
267 tlist[i].timeleft = offset;
268 tlist[i].timetowait = offset - tlist[i + 1].timeleft;
269 break;
270 }
271 }
272
273 /*
274 * Don't spam the users: skip our offset's warning broadcast if
275 * there's a broadcast scheduled after ours and it's relatively
276 * imminent.
277 */
278 if (offset > TEN_HOURS(10*60*60) ||
279 (offset > 0 && tlist[i].timetowait < tlist[i+1].timetowait / 5))
280 broadcast = 0;
281
282 for (logged = 0; i < tlistlen; i++) {
283 if (broadcast)
284 timewarn(tlist[i].timeleft);
285 broadcast = 1;
286 if (!logged && tlist[i].timeleft <= NOLOG_TIME(5*60)) {
287 logged = 1;
288 nolog(tlist[i].timeleft);
289 }
290 timeout.tv_sec = tlist[i].timetowait;
291 timeout.tv_nsec = 0;
292 nanosleep(&timeout, NULL((void *)0));
293 }
294 die_you_gravy_sucking_pig_dog();
295}
296
297static char *restricted_environ[] = {
298 "PATH=" _PATH_STDPATH"/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin",
299 NULL((void *)0)
300};
301
302void
303timewarn(time_t timeleft)
304{
305 static char hostname[HOST_NAME_MAX255+1];
306 char when[64];
307 struct tm *lt;
308 static int first;
309 int fd[2];
310 pid_t pid, wpid;
311
312 if (!first++)
313 (void)gethostname(hostname, sizeof(hostname));
314
315 if (pipe(fd) == -1) {
316 syslog(LOG_ERR3, "pipe: %m");
317 return;
318 }
319 switch (pid = fork()) {
320 case -1:
321 syslog(LOG_ERR3, "fork: %m");
322 close(fd[0]);
323 close(fd[1]);
324 return;
325 case 0:
326 if (dup2(fd[0], STDIN_FILENO0) == -1) {
327 syslog(LOG_ERR3, "dup2: %m");
328 _exit(1);
329 }
330 if (fd[0] != STDIN_FILENO0)
331 close(fd[0]);
332 close(fd[1]);
333 /* wall(1)'s undocumented '-n' flag suppresses its banner. */
334 execle(_PATH_WALL"/usr/bin/wall", _PATH_WALL"/usr/bin/wall", "-n", (char *)NULL((void *)0),
335 restricted_environ);
336 syslog(LOG_ERR3, "%s: %m", _PATH_WALL"/usr/bin/wall");
337 _exit(1);
338 default:
339 close(fd[0]);
340 }
341
342 dprintf(fd[1],
343 "\007*** %sSystem shutdown message from %s@%s ***\007\n",
344 timeleft ? "": "FINAL ", whom, hostname);
345
346 if (timeleft > 10 * 60) {
347 shuttime = time(NULL((void *)0)) + timeleft;
348 lt = localtime(&shuttime);
349 strftime(when, sizeof(when), "%H:%M %Z", lt);
350 dprintf(fd[1], "System going down at %s\n\n", when);
351 } else if (timeleft > 59) {
352 dprintf(fd[1], "System going down in %lld minute%s\n\n",
353 (long long)(timeleft / 60), (timeleft > 60) ? "s" : "");
354 } else if (timeleft)
355 dprintf(fd[1], "System going down in 30 seconds\n\n");
356 else
357 dprintf(fd[1], "System going down IMMEDIATELY\n\n");
358
359 if (mbuflen)
360 (void)write(fd[1], mbuf, mbuflen);
361 close(fd[1]);
362
363 /*
364 * If we wait longer than 30 seconds for wall(1) to exit we'll
365 * throw off our schedule.
366 */
367 signal(SIGALRM14, timeout);
368 siginterrupt(SIGALRM14, 1);
369 alarm(30);
370 while ((wpid = wait(NULL((void *)0))) != pid && !timed_out)
Although the value stored to 'wpid' is used in the enclosing expression, the value is never actually read from 'wpid'
371 continue;
372 alarm(0);
373 signal(SIGALRM14, SIG_DFL(void (*)(int))0);
374 if (timed_out) {
375 syslog(LOG_NOTICE5,
376 "wall[%ld] is taking too long to exit; continuing",
377 (long)pid);
378 timed_out = 0;
379 }
380}
381
382void
383timeout(int signo)
384{
385 timed_out = 1;
386}
387
388void
389die_you_gravy_sucking_pig_dog(void)
390{
391
392 syslog(LOG_NOTICE5, "%s by %s: %s",
393 doreboot ? "reboot" : dopower ? "power-down" : dohalt ? "halt" :
394 "shutdown", whom, mbuf);
395 (void)sleep(2);
396
397 (void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
398 if (killflg) {
399 (void)printf("\rbut you'll have to do it yourself\r\n");
400 finish(0);
401 }
402 if (dofast)
403 doitfast();
404
405 if (pledge("stdio rpath wpath cpath tty id proc exec", NULL((void *)0)) == -1)
406 err(1, "pledge");
407
408#ifdef DEBUG
409 if (doreboot)
410 (void)printf("reboot");
411 else if (dopower)
412 (void)printf("power-down");
413 else if (dohalt)
414 (void)printf("halt");
415 if (nosync)
416 (void)printf(" no sync");
417 if (dofast)
418 (void)printf(" no fsck");
419 if (dodump)
420 (void)printf(" with dump");
421 (void)printf("\nkill -HUP 1\n");
422#else
423 if (dohalt || dopower || doreboot) {
424 char *args[10];
425 char **arg, *path;
426
427 if (pledge("stdio exec", NULL((void *)0)) == -1)
428 err(1, "pledge");
429
430 arg = &args[0];
431 if (doreboot) {
432 path = _PATH_REBOOT"/sbin/reboot";
433 *arg++ = "reboot";
434 } else {
435 path = _PATH_HALT"/sbin/halt";
436 *arg++ = "halt";
437 }
438 *arg++ = "-l";
439 if (dopower)
440 *arg++ = "-p";
441 if (nosync)
442 *arg++ = "-n";
443 if (dodump)
444 *arg++ = "-d";
445 *arg++ = NULL((void *)0);
446 execve(path, args, NULL((void *)0));
447 syslog(LOG_ERR3, "shutdown: can't exec %s: %m.", path);
448 warn("%s", path);
449 }
450 if (access(_PATH_RC"/etc/rc", R_OK0x04) != -1) {
451 pid_t pid;
452 struct termios t;
453 int fd;
454
455 switch ((pid = fork())) {
456 case -1:
457 break;
458 case 0:
459 if (revoke(_PATH_CONSOLE"/dev/console") == -1)
460 perror("revoke");
461 if (setsid() == -1)
462 perror("setsid");
463 fd = open(_PATH_CONSOLE"/dev/console", O_RDWR0x0002);
464 if (fd == -1)
465 perror("open");
466 dup2(fd, 0);
467 dup2(fd, 1);
468 dup2(fd, 2);
469 if (fd > 2)
470 close(fd);
471
472 /* At a minimum... */
473 tcgetattr(0, &t);
474 t.c_oflag |= (ONLCR0x00000002 | OPOST0x00000001);
475 tcsetattr(0, TCSANOW0, &t);
476
477 execl(_PATH_BSHELL"/bin/sh", "sh", _PATH_RC"/etc/rc", "shutdown", (char *)NULL((void *)0));
478 _exit(1);
479 default:
480 waitpid(pid, NULL((void *)0), 0);
481 }
482 }
483 (void)kill(1, SIGTERM15); /* to single user */
484#endif
485 finish(0);
486}
487
488#define ATOI2(p)(p[0] - '0') * 10 + (p[1] - '0'); p += 2; (p[0] - '0') * 10 + (p[1] - '0'); p += 2;
489
490void
491getoffset(char *timearg)
492{
493 char when[64];
494 const char *errstr;
495 struct tm *lt;
496 int this_year;
497 time_t minutes, now;
498 char *p;
499
500 if (!strcasecmp(timearg, "now")) { /* now */
501 offset = 0;
502 return;
503 }
504
505 if (timearg[0] == '+') { /* +minutes */
506 minutes = strtonum(timearg, 0, INT_MAX2147483647, &errstr);
507 if (errstr)
508 errx(1, "relative offset is %s: %s", errstr, timearg);
509 offset = minutes * 60;
510 return;
511 }
512
513 /* handle hh:mm by getting rid of the colon */
514 for (p = timearg; *p; ++p) {
515 if (!isascii((unsigned char)*p) || !isdigit((unsigned char)*p)) {
516 if (*p == ':' && strlen(p) == 3) {
517 p[0] = p[1];
518 p[1] = p[2];
519 p[2] = '\0';
520 } else
521 badtime();
522 }
523 }
524
525 unsetenv("TZ"); /* OUR timezone */
526 time(&now);
527 lt = localtime(&now); /* current time val */
528
529 switch (strlen(timearg)) {
530 case 10:
531 this_year = lt->tm_year;
532 lt->tm_year = ATOI2(timearg)(timearg[0] - '0') * 10 + (timearg[1] - '0'); timearg += 2;;
533 /*
534 * check if the specified year is in the next century.
535 * allow for one year of user error as many people will
536 * enter n - 1 at the start of year n.
537 */
538 if (lt->tm_year < (this_year % 100) - 1)
539 lt->tm_year += 100;
540 /* adjust for the year 2000 and beyond */
541 lt->tm_year += (this_year - (this_year % 100));
542 /* FALLTHROUGH */
543 case 8:
544 lt->tm_mon = ATOI2(timearg)(timearg[0] - '0') * 10 + (timearg[1] - '0'); timearg += 2;;
545 if (--lt->tm_mon < 0 || lt->tm_mon > 11)
546 badtime();
547 /* FALLTHROUGH */
548 case 6:
549 lt->tm_mday = ATOI2(timearg)(timearg[0] - '0') * 10 + (timearg[1] - '0'); timearg += 2;;
550 if (lt->tm_mday < 1 || lt->tm_mday > 31)
551 badtime();
552 /* FALLTHROUGH */
553 case 4:
554 lt->tm_hour = ATOI2(timearg)(timearg[0] - '0') * 10 + (timearg[1] - '0'); timearg += 2;;
555 if (lt->tm_hour < 0 || lt->tm_hour > 23)
556 badtime();
557 lt->tm_min = ATOI2(timearg)(timearg[0] - '0') * 10 + (timearg[1] - '0'); timearg += 2;;
558 if (lt->tm_min < 0 || lt->tm_min > 59)
559 badtime();
560 lt->tm_sec = 0;
561 if ((shuttime = mktime(lt)) == -1)
562 badtime();
563 if ((offset = shuttime - now) < 0) {
564 strftime(when, sizeof(when), "%a %b %e %T %Z %Y", lt);
565 errx(1, "time is already past: %s", when);
566 }
567 break;
568 default:
569 badtime();
570 }
571}
572
573void
574doitfast(void)
575{
576 int fastfd;
577
578 if ((fastfd = open(_PATH_FASTBOOT"/fastboot", O_WRONLY0x0001|O_CREAT0x0200|O_TRUNC0x0400,
579 0664)) >= 0) {
580 dprintf(fastfd, "fastboot file for fsck\n");
581 close(fastfd);
582 }
583}
584
585void
586nolog(time_t timeleft)
587{
588 char when[64];
589 struct tm *tm;
590 int logfd;
591
592 (void)unlink(_PATH_NOLOGIN"/etc/nologin"); /* in case linked to another file */
593 (void)signal(SIGINT2, finish);
594 (void)signal(SIGHUP1, finish);
595 (void)signal(SIGQUIT3, finish);
596 (void)signal(SIGTERM15, finish);
597 shuttime = time(NULL((void *)0)) + timeleft;
598 tm = localtime(&shuttime);
599 if (tm && (logfd = open(_PATH_NOLOGIN"/etc/nologin", O_WRONLY0x0001|O_CREAT0x0200|O_TRUNC0x0400,
600 0664)) >= 0) {
601 strftime(when, sizeof(when), "at %H:%M %Z", tm);
602 dprintf(logfd, "\n\nNO LOGINS: System going down %s\n\n", when);
603 close(logfd);
604 }
605}
606
607void
608finish(int signo)
609{
610 if (!killflg)
611 (void)unlink(_PATH_NOLOGIN"/etc/nologin");
612 if (signo == 0)
613 exit(0);
614 else
615 _exit(0);
616}
617
618void
619badtime(void)
620{
621 errx(1, "bad time format.");
622}
623
624void
625usage(void)
626{
627 fprintf(stderr(&__sF[2]),
628 "usage: shutdown [-] [-dfhknpr] time [warning-message ...]\n");
629 exit(1);
630}