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 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #include <locale.h> 31 #include "stdio.h" 32 #include "signal.h" 33 #include "string.h" 34 #include "sys/types.h" 35 #include "errno.h" 36 #include "stdlib.h" 37 38 #include "lp.h" 39 #include "msgs.h" 40 41 #define WHO_AM_I I_AM_LPSHUT 42 #include "oam.h" 43 44 void startup(), 45 cleanup(), 46 done(); 47 48 /* 49 * There are no sections of code in this progam that have to be 50 * protected from interrupts. We do want to catch them, however, 51 * so we can clean up properly. 52 */ 53 54 /** 55 ** main() 56 **/ 57 58 int 59 main(int argc, char *argv[]) 60 { 61 char msgbuf[MSGMAX]; 62 char * tempo; 63 64 int mtype; 65 66 short status; 67 68 69 (void) setlocale (LC_ALL, ""); 70 71 #if !defined(TEXT_DOMAIN) 72 #define TEXT_DOMAIN "SYS_TEST" 73 #endif 74 (void) textdomain(TEXT_DOMAIN); 75 76 if (argc > 1) 77 if (STREQU(argv[1], "-?")) { 78 printf (gettext("usage: lpshut\n")); 79 exit (0); 80 81 } else { 82 LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[1]); 83 exit (1); 84 } 85 86 87 startup (); 88 89 if ((tempo = getenv("LPSHUT")) && STREQU(tempo, "slow")) 90 (void)putmessage (msgbuf, S_SHUTDOWN, 0); 91 else 92 (void)putmessage (msgbuf, S_SHUTDOWN, 1); 93 94 if (msend(msgbuf) == -1) { 95 LP_ERRMSG (ERROR, E_LP_MSEND); 96 done (1); 97 } 98 if (mrecv(msgbuf, sizeof(msgbuf)) == -1) { 99 LP_ERRMSG (ERROR, E_LP_MRECV); 100 done (1); 101 } 102 103 mtype = getmessage(msgbuf, R_SHUTDOWN, &status); 104 if (mtype != R_SHUTDOWN) { 105 LP_ERRMSG1 (ERROR, E_LP_BADREPLY, mtype); 106 done (1); 107 } 108 109 switch (status) { 110 111 case MOK: 112 printf (gettext("Print services stopped.\n")); 113 done (0); 114 115 case MNOPERM: 116 LP_ERRMSG (WARNING, E_SHT_CANT); 117 done (1); 118 119 default: 120 LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); 121 done (1); 122 } 123 /*NOTREACHED*/ 124 return (0); 125 } 126 127 /** 128 ** startup() - OPEN MESSAGE QUEUE TO SPOOLER 129 **/ 130 131 void startup () 132 { 133 void catch(); 134 135 /* 136 * Open a private queue for messages to the Spooler. 137 * An error is deadly. 138 */ 139 if (mopen() == -1) { 140 141 switch (errno) { 142 case ENOMEM: 143 case ENOSPC: 144 LP_ERRMSG (ERROR, E_LP_MLATER); 145 exit (1); 146 /*NOTREACHED*/ 147 148 default: 149 printf (gettext("Print services already stopped.\n")); 150 exit (1); 151 /*NOTREACHED*/ 152 } 153 } 154 155 /* 156 * Now that the queue is open, quickly trap signals 157 * that we might get so we'll be able to close the 158 * queue again, regardless of what happens. 159 */ 160 if(signal(SIGHUP, SIG_IGN) != SIG_IGN) 161 signal(SIGHUP, catch); 162 if(signal(SIGINT, SIG_IGN) != SIG_IGN) 163 signal(SIGINT, catch); 164 if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) 165 signal(SIGQUIT, catch); 166 if(signal(SIGTERM, SIG_IGN) != SIG_IGN) 167 signal(SIGTERM, catch); 168 169 return; 170 } 171 172 /** 173 ** catch() - CATCH INTERRUPT, HANGUP, ETC. 174 **/ 175 176 void catch (sig) 177 int sig; 178 { 179 signal (sig, SIG_IGN); 180 done (1); 181 } 182 183 /** 184 ** cleanup() - CLOSE THE MESSAGE QUEUE TO THE SPOOLER 185 **/ 186 187 void cleanup () 188 { 189 mclose (); 190 return; 191 } 192 193 /** 194 ** done() - CLEANUP AND EXIT 195 **/ 196 197 void done (ec) 198 int ec; 199 { 200 cleanup (); 201 exit (ec); 202 } 203