xref: /illumos-gate/usr/src/cmd/lp/cmd/lpshut.c (revision 2a8bcb4e)
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
main(int argc,char * argv[])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 
startup()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 
catch(sig)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 
cleanup()187 void			cleanup ()
188 {
189 	mclose ();
190 	return;
191 }
192 
193 /**
194  ** done() - CLEANUP AND EXIT
195  **/
196 
done(ec)197 void			done (ec)
198 	int			ec;
199 {
200 	cleanup ();
201 	exit (ec);
202 }
203