1 /*
2 * The new sysinstall program.
3 *
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
6 *
7 * $FreeBSD: stable/9/usr.sbin/sysinstall/msg.c 211417 2010-08-17 09:39:06Z brucec $
8 *
9 * Copyright (c) 1995
10 * Jordan Hubbard. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
18 * point in the file.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37 #include <sys/ioctl.h>
38 #include <sys/consio.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41
42 #include <netinet/in.h>
43 #include <netdb.h>
44
45 #include <stdarg.h>
46 #include <syslog.h>
47
48 #include "sysinstall.h"
49
50 Boolean
isDebug(void)51 isDebug(void)
52 {
53 char *cp;
54
55 return (cp = variable_get(VAR_DEBUG)) && strcmp(cp, "no");
56 }
57
58 static Boolean
isNetworkUp(void)59 isNetworkUp(void)
60 {
61 if (!(RunningAsInit) ||
62 (variable_check("NETWORK_CONFIGURED=NO")) != TRUE) {
63 return TRUE;
64 }
65
66 return FALSE;
67 }
68
69 void
msgSyslog(const char * errstr)70 msgSyslog(const char *errstr)
71 {
72 struct sockaddr_in server;
73 struct hostent *hp;
74 char *host, *line;
75 int sock;
76
77 if (!isNetworkUp())
78 return;
79
80 if (!(host = variable_get(VAR_SYSLOG_SERVER)))
81 return;
82
83 if (!(hp = gethostbyname2(host, AF_INET)))
84 return;
85
86 if (!(sock = socket(AF_INET, SOCK_DGRAM, 0)))
87 return;
88
89 bzero(&server, sizeof(struct sockaddr_in));
90 server.sin_family = AF_INET;
91 server.sin_port = htons(514);
92 bcopy((char *)hp->h_addr, (char *)&server.sin_addr, hp->h_length);
93
94 asprintf(&line, "<%d>%s", LOG_NOTICE, errstr);
95 sendto(sock, line, strlen(line), 0, (struct sockaddr *)&server,
96 sizeof(struct sockaddr_in));
97
98 close(sock);
99 free(line);
100 }
101
102 /* Whack up an informational message on the status line, in stand-out */
103 void
msgYap(char * fmt,...)104 msgYap(char *fmt, ...)
105 {
106 va_list args;
107 char *errstr;
108 int attrs;
109
110 errstr = (char *)alloca(FILENAME_MAX);
111 va_start(args, fmt);
112 vsnprintf(errstr, FILENAME_MAX, fmt, args);
113 va_end(args);
114 attrs = getattrs(stdscr);
115 attrset(A_REVERSE);
116 mvaddstr(StatusLine, 0, errstr);
117 attrset(attrs);
118 refresh();
119 }
120
121 /* Whack up an informational message on the status line */
122 void
msgInfo(char * fmt,...)123 msgInfo(char *fmt, ...)
124 {
125 va_list args;
126 char *errstr;
127 int i, attrs;
128 char line[81];
129
130 attrs = getattrs(stdscr);
131 /* NULL is a special convention meaning "erase the old stuff" */
132 if (!fmt) {
133 move(StatusLine, 0);
134 clrtoeol();
135 return;
136 }
137 errstr = (char *)alloca(FILENAME_MAX);
138 va_start(args, fmt);
139 vsnprintf(errstr, FILENAME_MAX, fmt, args);
140 va_end(args);
141 memset(line, ' ', 80);
142 for (i = 0; i < 80; i++) {
143 if (errstr[i])
144 line[i] = errstr[i];
145 else
146 break;
147 }
148 line[80] = '\0';
149 attrset(ATTR_TITLE);
150 mvaddstr(StatusLine, 0, line);
151 attrset(attrs);
152 move(StatusLine, 79);
153 refresh();
154
155 msgSyslog(errstr);
156 }
157
158 /* Whack up a warning on the status line */
159 void
msgWarn(char * fmt,...)160 msgWarn(char *fmt, ...)
161 {
162 va_list args;
163 char *errstr;
164 int attrs;
165
166 errstr = (char *)alloca(FILENAME_MAX);
167 strcpy(errstr, "Warning: ");
168 va_start(args, fmt);
169 vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
170 va_end(args);
171 attrs = getattrs(stdscr);
172 beep();
173 attrset(ATTR_TITLE);
174 mvaddstr(StatusLine, 0, errstr);
175 attrset(attrs);
176 refresh();
177
178 /* we don't want this hitting syslog twice */
179 if (isDebug()) {
180 if (OnVTY)
181 msgDebug("Warning message `%s'\n", errstr);
182 else
183 msgSyslog(errstr);
184 }
185
186 }
187
188 /* Whack up an error on the status line */
189 void
msgError(char * fmt,...)190 msgError(char *fmt, ...)
191 {
192 va_list args;
193 char *errstr;
194 int attrs;
195
196 errstr = (char *)alloca(FILENAME_MAX);
197 strcpy(errstr, "Error: ");
198 va_start(args, fmt);
199 vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
200 va_end(args);
201 beep();
202 attrs = getattrs(stdscr);
203 attrset(ATTR_TITLE);
204 mvaddstr(StatusLine, 0, errstr);
205 attrset(attrs);
206 refresh();
207
208 /* we don't want this hitting syslog twice */
209 if (isDebug()) {
210 if (OnVTY)
211 msgDebug("Error message `%s'\n", errstr);
212 else
213 msgSyslog(errstr);
214 }
215 }
216
217 /* Whack up a fatal error on the status line */
218 void
msgFatal(char * fmt,...)219 msgFatal(char *fmt, ...)
220 {
221 va_list args;
222 char *errstr;
223 int attrs;
224
225 errstr = (char *)alloca(FILENAME_MAX);
226 strcpy(errstr, "Fatal Error: ");
227 va_start(args, fmt);
228 vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
229 va_end(args);
230 beep();
231 attrs = getattrs(stdscr);
232 attrset(ATTR_TITLE);
233 mvaddstr(StatusLine, 0, errstr);
234 addstr(" - ");
235 addstr("PRESS ANY KEY TO ");
236 if (RunningAsInit)
237 addstr("REBOOT");
238 else
239 addstr("QUIT");
240 attrset(attrs);
241 refresh();
242 if (OnVTY)
243 msgDebug("Fatal error `%s'!\n", errstr);
244 else
245 msgSyslog(errstr);
246 getch();
247 systemShutdown(1);
248 }
249
250 /* Put up a message in a popup confirmation box */
251 void
msgConfirm(char * fmt,...)252 msgConfirm(char *fmt, ...)
253 {
254 va_list args;
255 char *errstr;
256 WINDOW *w = savescr();
257
258 errstr = (char *)alloca(FILENAME_MAX);
259 va_start(args, fmt);
260 vsnprintf(errstr, FILENAME_MAX, fmt, args);
261 va_end(args);
262 use_helpline(NULL);
263 use_helpfile(NULL);
264 if (OnVTY) {
265 ioctl(0, VT_ACTIVATE, 1);
266 msgInfo(NULL);
267 }
268 dialog_notify(errstr);
269 restorescr(w);
270 }
271
272 /* Put up a message in a popup information box */
273 void
msgNotify(char * fmt,...)274 msgNotify(char *fmt, ...)
275 {
276 va_list args;
277 char *errstr;
278
279 errstr = (char *)alloca(FILENAME_MAX);
280 va_start(args, fmt);
281 vsnprintf(errstr, FILENAME_MAX, fmt, args);
282 va_end(args);
283 use_helpline(NULL);
284 use_helpfile(NULL);
285 if (isDebug())
286 msgDebug("Notify: %s\n", errstr);
287 dialog_msgbox(NULL, errstr, -1, -1, 0);
288 }
289
290 /* Put up a message in a popup yes/no box and return 0 for YES, 1 for NO */
291 int
msgYesNo(char * fmt,...)292 msgYesNo(char *fmt, ...)
293 {
294 va_list args;
295 char *errstr;
296 int ret;
297 WINDOW *w = savescr();
298
299 errstr = (char *)alloca(FILENAME_MAX);
300 va_start(args, fmt);
301 vsnprintf(errstr, FILENAME_MAX, fmt, args);
302 va_end(args);
303 use_helpline(NULL);
304 use_helpfile(NULL);
305 if (OnVTY) {
306 ioctl(0, VT_ACTIVATE, 1); /* Switch back */
307 msgInfo(NULL);
308 }
309 if (variable_get(VAR_NONINTERACTIVE))
310 return 0; /* If non-interactive, return YES all the time */
311 ret = dialog_yesno("User Confirmation Requested", errstr, -1, -1);
312 restorescr(w);
313 return ret;
314 }
315
316 /* Put up a message in a popup no/yes box and return 0 for YES, 1 for NO */
317 int
msgNoYes(char * fmt,...)318 msgNoYes(char *fmt, ...)
319 {
320 va_list args;
321 char *errstr;
322 int ret;
323 WINDOW *w = savescr();
324
325 errstr = (char *)alloca(FILENAME_MAX);
326 va_start(args, fmt);
327 vsnprintf(errstr, FILENAME_MAX, fmt, args);
328 va_end(args);
329 use_helpline(NULL);
330 use_helpfile(NULL);
331 if (OnVTY) {
332 ioctl(0, VT_ACTIVATE, 1); /* Switch back */
333 msgInfo(NULL);
334 }
335 if (variable_get(VAR_NONINTERACTIVE))
336 return 1; /* If non-interactive, return NO all the time */
337 ret = dialog_noyes("User Confirmation Requested", errstr, -1, -1);
338 restorescr(w);
339 return ret;
340 }
341
342 /* Put up a message in an input box and return the value */
343 char *
msgGetInput(char * buf,char * fmt,...)344 msgGetInput(char *buf, char *fmt, ...)
345 {
346 va_list args;
347 char *errstr;
348 static char input_buffer[256];
349 int rval;
350 WINDOW *w = savescr();
351
352 errstr = (char *)alloca(FILENAME_MAX);
353 va_start(args, fmt);
354 vsnprintf(errstr, FILENAME_MAX, fmt, args);
355 va_end(args);
356 use_helpline(NULL);
357 use_helpfile(NULL);
358 if (buf)
359 SAFE_STRCPY(input_buffer, buf);
360 else
361 input_buffer[0] = '\0';
362 if (OnVTY) {
363 ioctl(0, VT_ACTIVATE, 1); /* Switch back */
364 msgInfo(NULL);
365 }
366 rval = dialog_inputbox("Value Required", errstr, -1, -1, input_buffer);
367 restorescr(w);
368 if (!rval)
369 return input_buffer;
370 else
371 return NULL;
372 }
373
374 /* Write something to the debugging port */
375 void
msgDebug(char * fmt,...)376 msgDebug(char *fmt, ...)
377 {
378 va_list args;
379 char *dbg;
380
381 if (DebugFD == -1)
382 return;
383 dbg = (char *)alloca(FILENAME_MAX);
384 strcpy(dbg, "DEBUG: ");
385 va_start(args, fmt);
386 vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
387 va_end(args);
388
389 msgSyslog(dbg);
390
391 write(DebugFD, dbg, strlen(dbg));
392 }
393
394 /* Tell the user there's some output to go look at */
395 void
msgWeHaveOutput(char * fmt,...)396 msgWeHaveOutput(char *fmt, ...)
397 {
398 va_list args;
399 char *errstr;
400 WINDOW *w = savescr();
401
402 errstr = (char *)alloca(FILENAME_MAX);
403 va_start(args, fmt);
404 vsnprintf(errstr, FILENAME_MAX, fmt, args);
405 va_end(args);
406 use_helpline(NULL);
407 use_helpfile(NULL);
408 msgDebug("Notify: %s\n", errstr);
409 dialog_clear_norefresh();
410 sleep(2);
411 dialog_msgbox(NULL, errstr, -1, -1, 0);
412 restorescr(w);
413 }
414
415 /* Simple versions of msgConfirm() and msgNotify() for calling from scripts */
416 int
msgSimpleConfirm(char * str)417 msgSimpleConfirm(char *str)
418 {
419 msgConfirm("%s", str);
420 return DITEM_SUCCESS;
421 }
422
423 int
msgSimpleNotify(char * str)424 msgSimpleNotify(char *str)
425 {
426 msgNotify("%s", str);
427 return DITEM_SUCCESS;
428 }
429