17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
327c478bd9Sstevel@tonic-gate * The Regents of the University of California
337c478bd9Sstevel@tonic-gate * All Rights Reserved
347c478bd9Sstevel@tonic-gate *
357c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
367c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
377c478bd9Sstevel@tonic-gate * contributors.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate #include <stdio.h>
437c478bd9Sstevel@tonic-gate #include <ctype.h>
447c478bd9Sstevel@tonic-gate #include <setjmp.h>
457c478bd9Sstevel@tonic-gate #include <utmpx.h>
467c478bd9Sstevel@tonic-gate #include <pwd.h>
477c478bd9Sstevel@tonic-gate #include <time.h>
487c478bd9Sstevel@tonic-gate #include <sys/time.h>
497c478bd9Sstevel@tonic-gate #include <sys/resource.h>
507c478bd9Sstevel@tonic-gate #include <sys/param.h>
517c478bd9Sstevel@tonic-gate #include <sys/types.h>
527c478bd9Sstevel@tonic-gate #include <sys/errno.h>
537c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
547c478bd9Sstevel@tonic-gate #include <rpc/pmap_clnt.h>
557c478bd9Sstevel@tonic-gate #include <rpcsvc/mount.h>
567c478bd9Sstevel@tonic-gate #include <rpcsvc/rwall.h>
577c478bd9Sstevel@tonic-gate #include <sys/socket.h>
587c478bd9Sstevel@tonic-gate #include <netinet/in.h>
597c478bd9Sstevel@tonic-gate #include <netdb.h>
607c478bd9Sstevel@tonic-gate #include <locale.h>
617c478bd9Sstevel@tonic-gate #include <sys/syslog.h>
627c478bd9Sstevel@tonic-gate #include <zone.h>
637c478bd9Sstevel@tonic-gate #include <signal.h>
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate * /usr/etc/shutdown when [messages]
677c478bd9Sstevel@tonic-gate *
687c478bd9Sstevel@tonic-gate * allow super users to tell users and remind users
697c478bd9Sstevel@tonic-gate * of iminent shutdown of unix
707c478bd9Sstevel@tonic-gate * and shut it down automatically
717c478bd9Sstevel@tonic-gate * and even reboot or halt the machine if they desire
727c478bd9Sstevel@tonic-gate */
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate #define EPATH "PATH=/usr/ucb:/usr/bin:/usr/sbin:"
757c478bd9Sstevel@tonic-gate #define REBOOT "/usr/sbin/reboot"
767c478bd9Sstevel@tonic-gate #define HALT "/usr/sbin/halt"
777c478bd9Sstevel@tonic-gate #define MAXINTS 20
787c478bd9Sstevel@tonic-gate #define HOURS *3600
797c478bd9Sstevel@tonic-gate #define MINUTES *60
807c478bd9Sstevel@tonic-gate #define SECONDS
817c478bd9Sstevel@tonic-gate #define NLOG 600 /* no of bytes possible for message */
827c478bd9Sstevel@tonic-gate #define NOLOGTIME 5 MINUTES
837c478bd9Sstevel@tonic-gate #define IGNOREUSER "sleeper"
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate struct hostlist {
867c478bd9Sstevel@tonic-gate char *host;
877c478bd9Sstevel@tonic-gate struct hostlist *nxt;
887c478bd9Sstevel@tonic-gate } *hostlist;
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate char hostname[MAXHOSTNAMELEN];
917c478bd9Sstevel@tonic-gate char mbuf[BUFSIZ];
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate extern char *malloc();
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate extern char *ctime();
967c478bd9Sstevel@tonic-gate extern struct tm *localtime();
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate extern char *strcpy();
997c478bd9Sstevel@tonic-gate extern char *strncat();
1007c478bd9Sstevel@tonic-gate extern off_t lseek();
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate struct utmpx *utmpx;
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate int sint;
1057c478bd9Sstevel@tonic-gate int stogo;
1067c478bd9Sstevel@tonic-gate char tpath[] = "/dev/";
1077c478bd9Sstevel@tonic-gate int nlflag = 1; /* nolog yet to be done */
1087c478bd9Sstevel@tonic-gate int killflg = 1;
1097c478bd9Sstevel@tonic-gate int doreboot = 0;
1107c478bd9Sstevel@tonic-gate int halt = 0;
1117c478bd9Sstevel@tonic-gate int fast = 0;
1127c478bd9Sstevel@tonic-gate char *nosync = NULL;
1137c478bd9Sstevel@tonic-gate char nosyncflag[] = "-n";
1147c478bd9Sstevel@tonic-gate char term[sizeof tpath + sizeof (utmpx->ut_line)];
1157c478bd9Sstevel@tonic-gate char tbuf[BUFSIZ];
1167c478bd9Sstevel@tonic-gate char nolog1[] = "\n\nNO LOGINS: System going down at %5.5s\n\n";
1177c478bd9Sstevel@tonic-gate char mesg[NLOG+1];
1187c478bd9Sstevel@tonic-gate #ifdef DEBUG
1197c478bd9Sstevel@tonic-gate char fastboot[] = "fastboot";
1207c478bd9Sstevel@tonic-gate #else
1217c478bd9Sstevel@tonic-gate char fastboot[] = "/fastboot";
1227c478bd9Sstevel@tonic-gate #endif
1237c478bd9Sstevel@tonic-gate char nologin[] = "/etc/nologin";
1247c478bd9Sstevel@tonic-gate time_t nowtime;
1257c478bd9Sstevel@tonic-gate jmp_buf alarmbuf;
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate struct interval {
1287c478bd9Sstevel@tonic-gate int stogo;
1297c478bd9Sstevel@tonic-gate int sint;
1307c478bd9Sstevel@tonic-gate } interval[] = {
1317c478bd9Sstevel@tonic-gate 4 HOURS, 1 HOURS,
1327c478bd9Sstevel@tonic-gate 2 HOURS, 30 MINUTES,
1337c478bd9Sstevel@tonic-gate 1 HOURS, 15 MINUTES,
1347c478bd9Sstevel@tonic-gate 30 MINUTES, 10 MINUTES,
1357c478bd9Sstevel@tonic-gate 15 MINUTES, 5 MINUTES,
1367c478bd9Sstevel@tonic-gate 10 MINUTES, 5 MINUTES,
1377c478bd9Sstevel@tonic-gate 5 MINUTES, 3 MINUTES,
1387c478bd9Sstevel@tonic-gate 2 MINUTES, 1 MINUTES,
1397c478bd9Sstevel@tonic-gate 1 MINUTES, 30 SECONDS,
1407c478bd9Sstevel@tonic-gate 0 SECONDS, 0 SECONDS
1417c478bd9Sstevel@tonic-gate };
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate char *msg1 = "shutdown: '%c' - unknown flag\n";
1447c478bd9Sstevel@tonic-gate char *msg2 = "Usage: shutdown [ -krhfn ] shutdowntime [ message ]\n";
1457c478bd9Sstevel@tonic-gate char *msg3 = "Usage: shutdown [ -krhfn ] shutdowntime [ message ]";
1467c478bd9Sstevel@tonic-gate char *msg4 = "Usage: shutdown [ -krhfn ] shutdowntime [ message ]\n";
1477c478bd9Sstevel@tonic-gate char *msg5 = "Usage: shutdown [ -krhfn ] shutdowntime [ message ]";
1487c478bd9Sstevel@tonic-gate char *msg6 = "\n\007\007System shutdown time has arrived\007\007\n";
1497c478bd9Sstevel@tonic-gate char *msg7 = "but you'll have to do it yourself\n";
1507c478bd9Sstevel@tonic-gate char *msg8 = "but you'll have to do it yourself";
1517c478bd9Sstevel@tonic-gate char *msg9 = "-l (without fsck's)\n";
1527c478bd9Sstevel@tonic-gate char *msg10 = "-l %s\n";
1537c478bd9Sstevel@tonic-gate char *msg11 = " (without fsck's)\n";
1547c478bd9Sstevel@tonic-gate char *msg12 = "That must be tomorrow\nCan't you wait till then?\n";
1557c478bd9Sstevel@tonic-gate char *msg13 = "That must be tomorrow";
1567c478bd9Sstevel@tonic-gate char *msg14 = "Can't you wait till then?";
1577c478bd9Sstevel@tonic-gate char *msg15 = "\007\007\t*** %sSystem shutdown message from %s@%s ***\r\n\n";
1587c478bd9Sstevel@tonic-gate char *msg16 = "System going down at %5.5s\r\n";
1597c478bd9Sstevel@tonic-gate char *msg17 = "System going down in %d minute%s\r\n";
1607c478bd9Sstevel@tonic-gate char *msg18 = "System going down in %d second%s\r\n";
1617c478bd9Sstevel@tonic-gate char *msg19 = "System going down IMMEDIATELY\r\n";
1627c478bd9Sstevel@tonic-gate char *msg20 = "Can't get PID for init\n";
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate char *shutter, *getlogin();
1657c478bd9Sstevel@tonic-gate
166*032624d5Sbasabi static void timeout(void);
167*032624d5Sbasabi static void gethostlist(void);
168*032624d5Sbasabi static void finish(char *, char *, int);
169*032624d5Sbasabi static void nolog(time_t);
170*032624d5Sbasabi static void rprintf(char *, char *);
171*032624d5Sbasabi static void rwarn(char *, time_t, time_t, char *, int);
172*032624d5Sbasabi static void doitfast(void);
173*032624d5Sbasabi static void warn(FILE *, time_t, time_t, char *, int);
174*032624d5Sbasabi static time_t getsdt(char *);
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate pid_t
get_initpid(void)177*032624d5Sbasabi get_initpid(void)
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate pid_t init_pid;
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate if (zone_getattr(getzoneid(), ZONE_ATTR_INITPID, &init_pid,
1827c478bd9Sstevel@tonic-gate sizeof (init_pid)) != sizeof (init_pid)) {
1837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(msg20));
1847c478bd9Sstevel@tonic-gate exit(1);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate return (init_pid);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)1907c478bd9Sstevel@tonic-gate main(int argc, char **argv)
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate int i;
1937c478bd9Sstevel@tonic-gate char *f;
1947c478bd9Sstevel@tonic-gate char *ts;
1957c478bd9Sstevel@tonic-gate time_t sdt;
1967c478bd9Sstevel@tonic-gate int h, m;
1977c478bd9Sstevel@tonic-gate int first;
1987c478bd9Sstevel@tonic-gate void finish_sig();
1997c478bd9Sstevel@tonic-gate FILE *termf;
2007c478bd9Sstevel@tonic-gate struct passwd *pw, *getpwuid();
2017c478bd9Sstevel@tonic-gate extern char *strcat();
2027c478bd9Sstevel@tonic-gate extern uid_t geteuid();
2037c478bd9Sstevel@tonic-gate struct hostlist *hl;
2047c478bd9Sstevel@tonic-gate char *shutdown_program;
2057c478bd9Sstevel@tonic-gate char *shutdown_action;
2067c478bd9Sstevel@tonic-gate int fd;
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
2117c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
2127c478bd9Sstevel@tonic-gate #endif
2137c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate audit_shutdown_setup(argc, argv);
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate shutter = getlogin();
2187c478bd9Sstevel@tonic-gate if (shutter == 0 && (pw = getpwuid(getuid())))
2197c478bd9Sstevel@tonic-gate shutter = pw->pw_name;
2207c478bd9Sstevel@tonic-gate if (shutter == 0)
2217c478bd9Sstevel@tonic-gate shutter = "???";
2227c478bd9Sstevel@tonic-gate (void) gethostname(hostname, sizeof (hostname));
2237c478bd9Sstevel@tonic-gate openlog("shutdown", 0, LOG_AUTH);
2247c478bd9Sstevel@tonic-gate argc--, argv++;
2257c478bd9Sstevel@tonic-gate while (argc > 0 && (f = argv[0], *f++ == '-')) {
2267c478bd9Sstevel@tonic-gate while (i = *f++) {
2277c478bd9Sstevel@tonic-gate switch (i) {
2287c478bd9Sstevel@tonic-gate case 'k':
2297c478bd9Sstevel@tonic-gate killflg = 0;
2307c478bd9Sstevel@tonic-gate continue;
2317c478bd9Sstevel@tonic-gate case 'n':
2327c478bd9Sstevel@tonic-gate nosync = nosyncflag;
2337c478bd9Sstevel@tonic-gate continue;
2347c478bd9Sstevel@tonic-gate case 'f':
2357c478bd9Sstevel@tonic-gate fast = 1;
2367c478bd9Sstevel@tonic-gate continue;
2377c478bd9Sstevel@tonic-gate case 'r':
2387c478bd9Sstevel@tonic-gate doreboot = 1;
2397c478bd9Sstevel@tonic-gate continue;
2407c478bd9Sstevel@tonic-gate case 'h':
2417c478bd9Sstevel@tonic-gate halt = 1;
2427c478bd9Sstevel@tonic-gate continue;
2437c478bd9Sstevel@tonic-gate default:
2447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(msg1),
2457c478bd9Sstevel@tonic-gate i);
2467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(msg2));
2477c478bd9Sstevel@tonic-gate finish(gettext(msg3), "", 1);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate argc--, argv++;
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate if (argc < 1) {
2537c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(msg4));
2547c478bd9Sstevel@tonic-gate finish(gettext(msg5), "", 1);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate if (doreboot && halt) {
2577c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2587c478bd9Sstevel@tonic-gate gettext("shutdown: Incompatible switches '-r' & '-h'\n"));
2597c478bd9Sstevel@tonic-gate finish(gettext("shutdown: Incompatible switches '-r' & '-h'"),
2607c478bd9Sstevel@tonic-gate "", 1);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate if (fast && (nosync == nosyncflag)) {
2637c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2647c478bd9Sstevel@tonic-gate gettext("shutdown: Incompatible switches '-f' & '-n'\n"));
2657c478bd9Sstevel@tonic-gate finish(gettext("shutdown: Incompatible switches '-f' & '-n'"),
2667c478bd9Sstevel@tonic-gate "", 1);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate if (geteuid()) {
2697c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("shutdown: NOT super-user\n"));
2707c478bd9Sstevel@tonic-gate finish(gettext("shutdown: NOT super-user"), "", 1);
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate gethostlist();
2737c478bd9Sstevel@tonic-gate nowtime = time((time_t *)NULL);
2747c478bd9Sstevel@tonic-gate sdt = getsdt(argv[0]);
2757c478bd9Sstevel@tonic-gate argc--, argv++;
2767c478bd9Sstevel@tonic-gate mesg[0] = '\0';
2777c478bd9Sstevel@tonic-gate i = 0;
2787c478bd9Sstevel@tonic-gate while (argc-- > 0) {
2797c478bd9Sstevel@tonic-gate if (i + strlen(*argv) > NLOG)
2807c478bd9Sstevel@tonic-gate break; /* no more room for the message */
2817c478bd9Sstevel@tonic-gate i += strlen(*argv) + 1;
2827c478bd9Sstevel@tonic-gate (void) strcat(mesg, *argv++);
2837c478bd9Sstevel@tonic-gate (void) strcat(mesg, " ");
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate if (i != 0)
2867c478bd9Sstevel@tonic-gate mesg[i - 1] = '\0'; /* remove trailing blank */
2877c478bd9Sstevel@tonic-gate m = ((stogo = sdt - nowtime) + 30)/60;
2887c478bd9Sstevel@tonic-gate h = m/60;
2897c478bd9Sstevel@tonic-gate m %= 60;
2907c478bd9Sstevel@tonic-gate ts = ctime(&sdt);
2917c478bd9Sstevel@tonic-gate (void) printf(gettext("Shutdown at %5.5s (in "), ts+11);
2927c478bd9Sstevel@tonic-gate if (h > 0)
2937c478bd9Sstevel@tonic-gate (void) printf("%d hour%s ", h, h != 1 ? "s" : "");
2947c478bd9Sstevel@tonic-gate (void) printf("%d minute%s) ", m, m != 1 ? "s" : "");
2957c478bd9Sstevel@tonic-gate #ifndef DEBUG
2967c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN);
2977c478bd9Sstevel@tonic-gate (void) signal(SIGQUIT, SIG_IGN);
2987c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN);
2997c478bd9Sstevel@tonic-gate #endif
3007c478bd9Sstevel@tonic-gate (void) signal(SIGTTOU, SIG_IGN);
3017c478bd9Sstevel@tonic-gate (void) signal(SIGINT, finish_sig);
302*032624d5Sbasabi (void) signal(SIGALRM, (void(*)())timeout);
3037c478bd9Sstevel@tonic-gate (void) setpriority(PRIO_PROCESS, 0, PRIO_MIN);
3047c478bd9Sstevel@tonic-gate (void) fflush(stdout);
3057c478bd9Sstevel@tonic-gate #ifndef DEBUG
3067c478bd9Sstevel@tonic-gate if (i = fork()) {
3077c478bd9Sstevel@tonic-gate (void) printf(gettext("[pid %d]\n"), i);
3087c478bd9Sstevel@tonic-gate exit(0);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate #else
3117c478bd9Sstevel@tonic-gate (void) putc('\n', stdout);
3127c478bd9Sstevel@tonic-gate #endif
3137c478bd9Sstevel@tonic-gate sint = 1 HOURS;
3147c478bd9Sstevel@tonic-gate f = "";
3157c478bd9Sstevel@tonic-gate first = 1;
3167c478bd9Sstevel@tonic-gate if (doreboot) {
3177c478bd9Sstevel@tonic-gate shutdown_program = REBOOT;
3187c478bd9Sstevel@tonic-gate shutdown_action = "reboot";
3197c478bd9Sstevel@tonic-gate } else if (halt) {
3207c478bd9Sstevel@tonic-gate shutdown_program = HALT;
3217c478bd9Sstevel@tonic-gate shutdown_action = "halt";
3227c478bd9Sstevel@tonic-gate } else {
3237c478bd9Sstevel@tonic-gate shutdown_program = NULL;
3247c478bd9Sstevel@tonic-gate shutdown_action = "shutdown";
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate for (;;) {
3277c478bd9Sstevel@tonic-gate for (i = 0; stogo <= interval[i].stogo && interval[i].sint; i++)
3287c478bd9Sstevel@tonic-gate sint = interval[i].sint;
3297c478bd9Sstevel@tonic-gate if (stogo > 0 && (stogo-sint) < interval[i].stogo)
3307c478bd9Sstevel@tonic-gate sint = stogo - interval[i].stogo;
3317c478bd9Sstevel@tonic-gate if (stogo <= NOLOGTIME && nlflag) {
3327c478bd9Sstevel@tonic-gate nlflag = 0;
3337c478bd9Sstevel@tonic-gate nolog(sdt);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate if (sint >= stogo || sint == 0)
3367c478bd9Sstevel@tonic-gate f = "FINAL ";
3377c478bd9Sstevel@tonic-gate nowtime = time((time_t *)NULL);
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate setutxent();
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate while ((utmpx = getutxent()) != NULL) {
3427c478bd9Sstevel@tonic-gate if (utmpx->ut_name[0] &&
3437c478bd9Sstevel@tonic-gate strncmp(utmpx->ut_name, IGNOREUSER,
3447c478bd9Sstevel@tonic-gate sizeof (utmpx->ut_name))) {
3457c478bd9Sstevel@tonic-gate /*
3467c478bd9Sstevel@tonic-gate * don't write to pty's unless they're rlogin sessions
3477c478bd9Sstevel@tonic-gate */
3487c478bd9Sstevel@tonic-gate if (utmpx->ut_type != USER_PROCESS &&
3497c478bd9Sstevel@tonic-gate utmpx->ut_user[0] != '\0')
3507c478bd9Sstevel@tonic-gate continue;
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate if (setjmp(alarmbuf))
3537c478bd9Sstevel@tonic-gate continue;
3547c478bd9Sstevel@tonic-gate (void) strcpy(term, tpath);
3557c478bd9Sstevel@tonic-gate (void) strncat(term, utmpx->ut_line,
3567c478bd9Sstevel@tonic-gate sizeof (utmpx->ut_line));
3577c478bd9Sstevel@tonic-gate (void) alarm(5);
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate /* check if device is really a tty */
3607c478bd9Sstevel@tonic-gate if ((fd = open(term, O_WRONLY|O_NOCTTY)) == -1) {
3617c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Cannot open %s.\n"),
3627c478bd9Sstevel@tonic-gate term);
3637c478bd9Sstevel@tonic-gate (void) alarm(0);
3647c478bd9Sstevel@tonic-gate continue;
3657c478bd9Sstevel@tonic-gate } else {
3667c478bd9Sstevel@tonic-gate if (!isatty(fd)) {
3677c478bd9Sstevel@tonic-gate fprintf(stderr,
3687c478bd9Sstevel@tonic-gate gettext("%.*s in utmpx is not a tty\n"),
3697c478bd9Sstevel@tonic-gate sizeof (utmpx->ut_line), utmpx->ut_line);
3707c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "%.*s in utmpx is not "
3717c478bd9Sstevel@tonic-gate "a tty\n", sizeof (utmpx->ut_line),
3727c478bd9Sstevel@tonic-gate utmpx->ut_line);
3737c478bd9Sstevel@tonic-gate close(fd);
3747c478bd9Sstevel@tonic-gate (void) alarm(0);
3757c478bd9Sstevel@tonic-gate continue;
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate close(fd);
3797c478bd9Sstevel@tonic-gate #ifdef DEBUG
3807c478bd9Sstevel@tonic-gate if ((termf = stdout) != NULL)
3817c478bd9Sstevel@tonic-gate #else
3827c478bd9Sstevel@tonic-gate if ((termf = fopen(term, "w")) != NULL)
3837c478bd9Sstevel@tonic-gate #endif
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate (void) alarm(0);
3867c478bd9Sstevel@tonic-gate setbuf(termf, tbuf);
3877c478bd9Sstevel@tonic-gate (void) fprintf(termf, "\n\r\n");
3887c478bd9Sstevel@tonic-gate warn(termf, sdt, nowtime, f, first);
3897c478bd9Sstevel@tonic-gate (void) alarm(5);
3907c478bd9Sstevel@tonic-gate #ifdef DEBUG
3917c478bd9Sstevel@tonic-gate (void) fflush(termf);
3927c478bd9Sstevel@tonic-gate #else
3937c478bd9Sstevel@tonic-gate (void) fclose(termf);
3947c478bd9Sstevel@tonic-gate #endif
3957c478bd9Sstevel@tonic-gate (void) alarm(0);
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate } /* while */
3997c478bd9Sstevel@tonic-gate
4007c478bd9Sstevel@tonic-gate endutxent();
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate for (hl = hostlist; hl != NULL; hl = hl->nxt)
4037c478bd9Sstevel@tonic-gate rwarn(hl->host, sdt, nowtime, f, first);
4047c478bd9Sstevel@tonic-gate if (stogo <= 0) {
4057c478bd9Sstevel@tonic-gate (void) printf(gettext(msg6));
4067c478bd9Sstevel@tonic-gate if (*mesg)
4077c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "%s by %s: %s",
4087c478bd9Sstevel@tonic-gate shutdown_action, shutter, mesg);
4097c478bd9Sstevel@tonic-gate else
4107c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "%s by %s",
4117c478bd9Sstevel@tonic-gate shutdown_action, shutter);
4127c478bd9Sstevel@tonic-gate sleep(2);
4137c478bd9Sstevel@tonic-gate (void) unlink(nologin);
4147c478bd9Sstevel@tonic-gate if (!killflg) {
4157c478bd9Sstevel@tonic-gate (void) printf(gettext(msg7));
4167c478bd9Sstevel@tonic-gate finish(gettext(msg8), "", 0);
4177c478bd9Sstevel@tonic-gate }
4187c478bd9Sstevel@tonic-gate if (fast)
4197c478bd9Sstevel@tonic-gate doitfast();
4207c478bd9Sstevel@tonic-gate #ifndef DEBUG
4217c478bd9Sstevel@tonic-gate (void) putenv(EPATH);
4227c478bd9Sstevel@tonic-gate if (shutdown_program != NULL) {
4237c478bd9Sstevel@tonic-gate audit_shutdown_success();
4247c478bd9Sstevel@tonic-gate execlp(shutdown_program, shutdown_program,
4257c478bd9Sstevel@tonic-gate "-l", nosync, (char *)0);
4267c478bd9Sstevel@tonic-gate } else {
4277c478bd9Sstevel@tonic-gate if (geteuid() == 0) {
4287c478bd9Sstevel@tonic-gate audit_shutdown_success();
4297c478bd9Sstevel@tonic-gate sleep(5);
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate if (getzoneid() == GLOBAL_ZONEID) {
4327c478bd9Sstevel@tonic-gate (void) system(
4337c478bd9Sstevel@tonic-gate "/sbin/bootadm -a update_all");
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate (void) kill(get_initpid(), SIGINT); /* sync */
4377c478bd9Sstevel@tonic-gate (void) kill(get_initpid(), SIGINT); /* sync */
4387c478bd9Sstevel@tonic-gate sleep(20);
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate #else
4417c478bd9Sstevel@tonic-gate if (shutdown_program) {
4427c478bd9Sstevel@tonic-gate (void) printf("%s ", shutdown_program);
4437c478bd9Sstevel@tonic-gate if (fast)
4447c478bd9Sstevel@tonic-gate (void) printf(gettext(msg9));
4457c478bd9Sstevel@tonic-gate else if (nosync != NULL)
4467c478bd9Sstevel@tonic-gate (void) printf(gettext(msg10), nosync);
4477c478bd9Sstevel@tonic-gate else
4487c478bd9Sstevel@tonic-gate (void) printf(gettext("-l\n"));
4497c478bd9Sstevel@tonic-gate } else {
4507c478bd9Sstevel@tonic-gate (void) printf("/sbin/bootadm -a update_all");
4517c478bd9Sstevel@tonic-gate (void) printf("kill -INT 1");
4527c478bd9Sstevel@tonic-gate if (fast)
4537c478bd9Sstevel@tonic-gate (void) printf(gettext(msg11));
4547c478bd9Sstevel@tonic-gate else
4557c478bd9Sstevel@tonic-gate (void) printf("\n");
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate #endif
4587c478bd9Sstevel@tonic-gate finish("", "", 0);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate stogo = sdt - time((time_t *)NULL);
4617c478bd9Sstevel@tonic-gate if (stogo > 0 && sint > 0)
4627c478bd9Sstevel@tonic-gate sleep((unsigned)(sint < stogo ? sint : stogo));
4637c478bd9Sstevel@tonic-gate stogo -= sint;
4647c478bd9Sstevel@tonic-gate first = 0;
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate /* NOTREACHED */
4677c478bd9Sstevel@tonic-gate }
4687c478bd9Sstevel@tonic-gate
469*032624d5Sbasabi static time_t
getsdt(char * s)470*032624d5Sbasabi getsdt(char *s)
4717c478bd9Sstevel@tonic-gate {
4727c478bd9Sstevel@tonic-gate time_t t, t1, tim;
4737c478bd9Sstevel@tonic-gate char c;
4747c478bd9Sstevel@tonic-gate struct tm *lt;
4757c478bd9Sstevel@tonic-gate int c_count;
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate if (strcmp(s, "now") == 0)
4787c478bd9Sstevel@tonic-gate return (nowtime);
4797c478bd9Sstevel@tonic-gate if (*s == '+') {
4807c478bd9Sstevel@tonic-gate ++s;
4817c478bd9Sstevel@tonic-gate t = 0;
4827c478bd9Sstevel@tonic-gate for (c_count = 1; ; c_count++) {
4837c478bd9Sstevel@tonic-gate c = *s++;
4847c478bd9Sstevel@tonic-gate if (!isdigit(c)) {
4857c478bd9Sstevel@tonic-gate if (c_count == 1) {
4867c478bd9Sstevel@tonic-gate goto badform;
4877c478bd9Sstevel@tonic-gate } else {
4887c478bd9Sstevel@tonic-gate break;
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate t = t * 10 + c - '0';
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate if (t <= 0)
4947c478bd9Sstevel@tonic-gate t = 5;
4957c478bd9Sstevel@tonic-gate t *= 60;
4967c478bd9Sstevel@tonic-gate tim = time((time_t *)NULL) + t;
4977c478bd9Sstevel@tonic-gate return (tim);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate t = 0;
5007c478bd9Sstevel@tonic-gate while (strlen(s) > 2 && isdigit(*s))
5017c478bd9Sstevel@tonic-gate t = t * 10 + *s++ - '0';
5027c478bd9Sstevel@tonic-gate if (*s == ':')
5037c478bd9Sstevel@tonic-gate s++;
5047c478bd9Sstevel@tonic-gate if (t > 23)
5057c478bd9Sstevel@tonic-gate goto badform;
5067c478bd9Sstevel@tonic-gate tim = t*60;
5077c478bd9Sstevel@tonic-gate t = 0;
5087c478bd9Sstevel@tonic-gate while (isdigit(*s))
5097c478bd9Sstevel@tonic-gate t = t * 10 + *s++ - '0';
5107c478bd9Sstevel@tonic-gate if (t > 59)
5117c478bd9Sstevel@tonic-gate goto badform;
5127c478bd9Sstevel@tonic-gate tim += t;
5137c478bd9Sstevel@tonic-gate tim *= 60;
5147c478bd9Sstevel@tonic-gate t1 = time((time_t *)NULL);
5157c478bd9Sstevel@tonic-gate lt = localtime(&t1);
5167c478bd9Sstevel@tonic-gate t = lt->tm_sec + lt->tm_min*60 + lt->tm_hour*3600;
5177c478bd9Sstevel@tonic-gate if (tim < t || tim >= (24*3600)) {
5187c478bd9Sstevel@tonic-gate /* before now or after midnight */
5197c478bd9Sstevel@tonic-gate (void) printf(gettext(msg12));
5207c478bd9Sstevel@tonic-gate finish(gettext(msg13), gettext(msg14), 0);
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate return (t1 + tim - t);
5237c478bd9Sstevel@tonic-gate badform:
5247c478bd9Sstevel@tonic-gate (void) printf(gettext("Bad time format\n"));
5257c478bd9Sstevel@tonic-gate finish(gettext("Bad time format"), "", 0);
526*032624d5Sbasabi return (0);
5277c478bd9Sstevel@tonic-gate /* NOTREACHED */
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate
530*032624d5Sbasabi static void
warn(FILE * termf,time_t sdt,time_t now,char * type,int first)531*032624d5Sbasabi warn(FILE *termf, time_t sdt, time_t now, char *type, int first)
5327c478bd9Sstevel@tonic-gate {
5337c478bd9Sstevel@tonic-gate char *ts;
5347c478bd9Sstevel@tonic-gate time_t delay = sdt - now;
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate if (delay > 8)
5377c478bd9Sstevel@tonic-gate while (delay % 5)
5387c478bd9Sstevel@tonic-gate delay++;
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate (void) fprintf(termf, gettext(msg15), type, shutter, hostname);
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate ts = ctime(&sdt);
5437c478bd9Sstevel@tonic-gate if (delay > 10 MINUTES)
5447c478bd9Sstevel@tonic-gate (void) fprintf(termf, gettext(msg16), ts+11);
5457c478bd9Sstevel@tonic-gate else if (delay > 95 SECONDS) {
5467c478bd9Sstevel@tonic-gate (void) fprintf(termf, gettext(msg17), (delay+30)/60,
5477c478bd9Sstevel@tonic-gate (delay+30)/60 != 1 ? "s" : "");
5487c478bd9Sstevel@tonic-gate } else if (delay > 0) {
5497c478bd9Sstevel@tonic-gate (void) fprintf(termf, gettext(msg18), delay,
5507c478bd9Sstevel@tonic-gate delay != 1 ? "s" : "");
5517c478bd9Sstevel@tonic-gate } else
5527c478bd9Sstevel@tonic-gate (void) fprintf(termf, gettext(msg19));
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate if (first || sdt - now > 1 MINUTES) {
5557c478bd9Sstevel@tonic-gate if (*mesg)
5567c478bd9Sstevel@tonic-gate (void) fprintf(termf, "\t...%s\r\n", mesg);
5577c478bd9Sstevel@tonic-gate }
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate
560*032624d5Sbasabi static void
doitfast(void)561*032624d5Sbasabi doitfast(void)
5627c478bd9Sstevel@tonic-gate {
5637c478bd9Sstevel@tonic-gate FILE *fastd;
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate if ((fastd = fopen(fastboot, "w")) != NULL) {
5667c478bd9Sstevel@tonic-gate (void) putc('\n', fastd);
5677c478bd9Sstevel@tonic-gate (void) fclose(fastd);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate
571*032624d5Sbasabi static void
rwarn(char * host,time_t sdt,time_t now,char * type,int first)572*032624d5Sbasabi rwarn(char *host, time_t sdt, time_t now, char *type, int first)
5737c478bd9Sstevel@tonic-gate {
5747c478bd9Sstevel@tonic-gate char *ts;
5757c478bd9Sstevel@tonic-gate time_t delay = sdt - now;
5767c478bd9Sstevel@tonic-gate char *bufp;
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate if (delay > 8)
5797c478bd9Sstevel@tonic-gate while (delay % 5)
5807c478bd9Sstevel@tonic-gate delay++;
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate (void) sprintf(mbuf,
5837c478bd9Sstevel@tonic-gate "\007\007\t*** %sShutdown message for %s from %s@%s ***\r\n\n",
5847c478bd9Sstevel@tonic-gate type, hostname, shutter, hostname);
5857c478bd9Sstevel@tonic-gate ts = ctime(&sdt);
5867c478bd9Sstevel@tonic-gate bufp = mbuf + strlen(mbuf);
5877c478bd9Sstevel@tonic-gate if (delay > 10 MINUTES) {
5887c478bd9Sstevel@tonic-gate (void) sprintf(bufp, "%s going down at %5.5s\r\n", hostname,
5897c478bd9Sstevel@tonic-gate ts+11);
5907c478bd9Sstevel@tonic-gate } else if (delay > 95 SECONDS) {
5917c478bd9Sstevel@tonic-gate (void) sprintf(bufp, "%s going down in %d minute%s\r\n",
5927c478bd9Sstevel@tonic-gate hostname, (delay+30)/60, (delay+30)/60 != 1 ? "s" : "");
5937c478bd9Sstevel@tonic-gate } else if (delay > 0) {
5947c478bd9Sstevel@tonic-gate (void) sprintf(bufp, "%s going down in %d second%s\r\n",
5957c478bd9Sstevel@tonic-gate hostname, delay, delay != 1 ? "s" : "");
5967c478bd9Sstevel@tonic-gate } else {
5977c478bd9Sstevel@tonic-gate (void) sprintf(bufp, "%s going down IMMEDIATELY\r\n",
5987c478bd9Sstevel@tonic-gate hostname);
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate bufp = mbuf + strlen(mbuf);
6017c478bd9Sstevel@tonic-gate if (first || sdt - now > 1 MINUTES) {
6027c478bd9Sstevel@tonic-gate if (*mesg)
6037c478bd9Sstevel@tonic-gate (void) sprintf(bufp, "\t...%s\r\n", mesg);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate rprintf(host, mbuf);
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
608*032624d5Sbasabi static void
rprintf(char * host,char * bufp)609*032624d5Sbasabi rprintf(char *host, char *bufp)
6107c478bd9Sstevel@tonic-gate {
6117c478bd9Sstevel@tonic-gate int err;
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate #ifdef DEBUG
6147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("about to call %s\n"), host);
6157c478bd9Sstevel@tonic-gate #endif
6167c478bd9Sstevel@tonic-gate if (err = callrpcfast(host, (rpcprog_t)WALLPROG, (rpcvers_t)WALLVERS,
6177c478bd9Sstevel@tonic-gate (rpcproc_t)WALLPROC_WALL, xdr_dirpath, (char *)&bufp, xdr_void,
6187c478bd9Sstevel@tonic-gate (char *)NULL)) {
6197c478bd9Sstevel@tonic-gate #ifdef DEBUG
6207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("couldn't make rpc call: "));
6217c478bd9Sstevel@tonic-gate clnt_perrno(err);
6227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
6237c478bd9Sstevel@tonic-gate #endif
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate
627*032624d5Sbasabi static void
nolog(time_t sdt)628*032624d5Sbasabi nolog(time_t sdt)
6297c478bd9Sstevel@tonic-gate {
6307c478bd9Sstevel@tonic-gate FILE *nologf;
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate (void) unlink(nologin); /* in case linked to std file */
6337c478bd9Sstevel@tonic-gate if ((nologf = fopen(nologin, "w")) != NULL) {
6347c478bd9Sstevel@tonic-gate (void) fprintf(nologf, nolog1, (ctime(&sdt)) + 11);
6357c478bd9Sstevel@tonic-gate if (*mesg)
6367c478bd9Sstevel@tonic-gate (void) fprintf(nologf, "\t%s\n", mesg);
6377c478bd9Sstevel@tonic-gate (void) fclose(nologf);
6387c478bd9Sstevel@tonic-gate }
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate void
finish_sig(void)642*032624d5Sbasabi finish_sig(void)
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate finish("SIGINT", "", 1);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
647*032624d5Sbasabi static void
finish(char * s1,char * s2,int exitcode)648*032624d5Sbasabi finish(char *s1, char *s2, int exitcode)
6497c478bd9Sstevel@tonic-gate {
6507c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN);
6517c478bd9Sstevel@tonic-gate exit(exitcode);
6527c478bd9Sstevel@tonic-gate }
6537c478bd9Sstevel@tonic-gate
654*032624d5Sbasabi static void
timeout(void)655*032624d5Sbasabi timeout(void)
6567c478bd9Sstevel@tonic-gate {
6577c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, (void(*)())timeout);
6587c478bd9Sstevel@tonic-gate longjmp(alarmbuf, 1);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate
661*032624d5Sbasabi static void
gethostlist(void)662*032624d5Sbasabi gethostlist(void)
6637c478bd9Sstevel@tonic-gate {
6647c478bd9Sstevel@tonic-gate int s;
6657c478bd9Sstevel@tonic-gate struct mountbody *ml;
6667c478bd9Sstevel@tonic-gate struct hostlist *hl;
6677c478bd9Sstevel@tonic-gate struct sockaddr_in addr;
6687c478bd9Sstevel@tonic-gate CLIENT *cl;
6697c478bd9Sstevel@tonic-gate static struct timeval TIMEOUT = { 25, 0 };
6707c478bd9Sstevel@tonic-gate
6717c478bd9Sstevel@tonic-gate /*
6727c478bd9Sstevel@tonic-gate * check for portmapper
6737c478bd9Sstevel@tonic-gate */
6747c478bd9Sstevel@tonic-gate get_myaddress(&addr);
6757c478bd9Sstevel@tonic-gate s = socket(AF_INET, SOCK_STREAM, 0);
6767c478bd9Sstevel@tonic-gate if (s < 0)
6777c478bd9Sstevel@tonic-gate return;
6787c478bd9Sstevel@tonic-gate if (connect(s, (struct sockaddr *)&addr, sizeof (addr)) < 0)
6797c478bd9Sstevel@tonic-gate return;
6807c478bd9Sstevel@tonic-gate (void) close(s);
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate /*
6837c478bd9Sstevel@tonic-gate * First try tcp, then drop back to udp if
6847c478bd9Sstevel@tonic-gate * tcp is unavailable (an old version of mountd perhaps)
6857c478bd9Sstevel@tonic-gate * Using tcp is preferred because it can handle
6867c478bd9Sstevel@tonic-gate * arbitrarily long export lists.
6877c478bd9Sstevel@tonic-gate */
6887c478bd9Sstevel@tonic-gate cl = clnt_create(hostname, (ulong_t)MOUNTPROG, (ulong_t)MOUNTVERS,
6897c478bd9Sstevel@tonic-gate "tcp");
6907c478bd9Sstevel@tonic-gate if (cl == NULL) {
6917c478bd9Sstevel@tonic-gate cl = clnt_create(hostname, (ulong_t)MOUNTPROG,
6927c478bd9Sstevel@tonic-gate (ulong_t)MOUNTVERS, "udp");
6937c478bd9Sstevel@tonic-gate if (cl == NULL) {
6947c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) {
6957c478bd9Sstevel@tonic-gate clnt_pcreateerror("shutdown warning");
6967c478bd9Sstevel@tonic-gate }
6977c478bd9Sstevel@tonic-gate return;
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate ml = NULL;
7027c478bd9Sstevel@tonic-gate if (clnt_call(cl, MOUNTPROC_DUMP,
7037c478bd9Sstevel@tonic-gate xdr_void, 0, xdr_mountlist, (char *)&ml, TIMEOUT) != RPC_SUCCESS) {
7047c478bd9Sstevel@tonic-gate clnt_perror(cl, "shutdown warning");
7057c478bd9Sstevel@tonic-gate return;
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate for (; ml != NULL; ml = ml->ml_next) {
7087c478bd9Sstevel@tonic-gate for (hl = hostlist; hl != NULL; hl = hl->nxt)
7097c478bd9Sstevel@tonic-gate if (strcmp(ml->ml_hostname, hl->host) == 0)
7107c478bd9Sstevel@tonic-gate goto again;
7117c478bd9Sstevel@tonic-gate hl = (struct hostlist *)malloc(sizeof (struct hostlist));
7127c478bd9Sstevel@tonic-gate hl->host = ml->ml_hostname;
7137c478bd9Sstevel@tonic-gate hl->nxt = hostlist;
7147c478bd9Sstevel@tonic-gate hostlist = hl;
7157c478bd9Sstevel@tonic-gate again:;
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate }
7187c478bd9Sstevel@tonic-gate
7197c478bd9Sstevel@tonic-gate /*
7207c478bd9Sstevel@tonic-gate * Don't want to wait for usual portmapper timeout you get with
7217c478bd9Sstevel@tonic-gate * callrpc or clnt_call, so use rmtcall instead. Use timeout
7227c478bd9Sstevel@tonic-gate * of 8 secs, based on the per try timeout of 3 secs for rmtcall
7237c478bd9Sstevel@tonic-gate */
724*032624d5Sbasabi int
callrpcfast(char * host,rpcprog_t prognum,rpcprog_t versnum,rpcprog_t procnum,xdrproc_t inproc,xdrproc_t outproc,char * in,char * out)725*032624d5Sbasabi callrpcfast(char *host, rpcprog_t prognum, rpcprog_t versnum,
726*032624d5Sbasabi rpcprog_t procnum, xdrproc_t inproc, xdrproc_t outproc,
727*032624d5Sbasabi char *in, char *out)
7287c478bd9Sstevel@tonic-gate {
7297c478bd9Sstevel@tonic-gate struct sockaddr_in server_addr;
7307c478bd9Sstevel@tonic-gate struct hostent *hp;
7317c478bd9Sstevel@tonic-gate struct timeval rpctimeout;
7327c478bd9Sstevel@tonic-gate rpcport_t port;
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate if ((hp = gethostbyname(host)) == NULL)
7357c478bd9Sstevel@tonic-gate return ((int)RPC_UNKNOWNHOST);
7367c478bd9Sstevel@tonic-gate bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
7377c478bd9Sstevel@tonic-gate server_addr.sin_family = AF_INET;
7387c478bd9Sstevel@tonic-gate server_addr.sin_port = 0;
7397c478bd9Sstevel@tonic-gate rpctimeout.tv_sec = 8;
7407c478bd9Sstevel@tonic-gate rpctimeout.tv_usec = 0;
7417c478bd9Sstevel@tonic-gate return ((int)pmap_rmtcall(&server_addr, prognum, versnum, procnum,
7427c478bd9Sstevel@tonic-gate inproc, in, outproc, out, rpctimeout, &port));
7437c478bd9Sstevel@tonic-gate }
744