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