Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / dialog / dialog.c
1 /*
2  *  dialog - Display simple dialog boxes from shell scripts
3  *
4  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation; either version 2
9  *  of the License, or (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * $FreeBSD: src/gnu/usr.bin/dialog/dialog.c,v 1.12.6.1 2001/03/05 10:28:10 kris Exp $
21  *
22  *
23  *  HISTORY:
24  *
25  *  17/12/93 - Version 0.1 released.
26  *
27  *  19/12/93 - menu will now scroll if there are more items than can fit
28  *             on the screen.
29  *           - added 'checklist', a dialog box with a list of options that
30  *             can be turned on or off. A list of options that are on is
31  *             returned on exit.
32  *
33  *  20/12/93 - Version 0.15 released.
34  *
35  *  29/12/93 - Incorporated patch from Patrick J. Volkerding
36  *             (volkerdi@mhd1.moorhead.msus.edu) that made these changes:
37  *             - increased MAX_LEN to 2048
38  *             - added 'infobox', equivalent to a message box without pausing
39  *             - added option '--clear' that will clear the screen
40  *             - Explicit line breaking when printing prompt text can be
41  *               invoked by real newline '\n' besides the string "\n"
42  *           - an optional parameter '--title <string>' can be used to
43  *             specify a title string for the dialog box
44  *
45  *  03/01/94 - added 'textbox', a dialog box for displaying text from a file.
46  *           - Version 0.2 released.
47  *
48  *  04/01/94 - some fixes and improvements for 'textbox':
49  *             - fixed a bug that will cause a segmentation violation when a
50  *               line is longer than MAX_LEN characters. Lines will now be
51  *               truncated if they are longer than MAX_LEN characters.
52  *             - removed wrefresh() from print_line(). This will increase
53  *               efficiency of print_page() which calls print_line().
54  *             - display current position in the form of percentage into file.
55  *           - Version 0.21 released.
56  *
57  *  05/01/94 - some changes for faster screen update.
58  *
59  *  07/01/94 - much more flexible color settings. Can use all 16 colors
60  *             (8 normal, 8 highlight) of the Linux console.
61  *
62  *  08/01/94 - added run-time configuration using configuration file.
63  *
64  *  09/01/94 - some minor bug fixes and cleanups for menubox, checklist and
65  *             textbox.
66  *
67  *  11/01/94 - added a man page.
68  *
69  *  13/01/94 - some changes for easier porting to other Unix systems (tested
70  *             on Ultrix, SunOS and HPUX)
71  *           - Version 0.3 released.
72  *
73  *  08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk
74  *             Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
75  *             Fixed the wordwrap routine - it'll actually wrap properly now
76  *             Added a more 3D look to everything - having your own rc file could
77  *               prove 'interesting' to say the least :-)
78  *             Added radiolist option
79  *           - Version 0.4 released.
80  *
81  *  09/28/98 - Patches by Anatoly A. Orehovsky - tolik@mpeks.tomsk.su
82  *             Added ftree and tree options
83  *
84  */
85
86 #include <sys/types.h>
87
88 #include <stdio.h>
89 #include <stdlib.h>
90 #include <string.h>
91 #include <sys/wait.h>
92 #include <dialog.h>
93
94 void Usage(char *name);
95
96 int main(int argc, char *argv[])
97 {
98   int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
99   unsigned char *title = NULL;
100   unsigned char result[MAX_LEN];
101   char *hline = NULL, *hfile = NULL;
102
103   if (argc < 2) {
104     Usage(argv[0]);
105     exit(-1);
106   }
107   else if (!strcmp(argv[1], "--create-rc")) {
108 #ifdef HAVE_NCURSES
109     if (argc != 3) {
110       Usage(argv[0]);
111       exit(-1);
112     }
113     dialog_create_rc(argv[2]);
114     return 0;
115 #else
116     fprintf(stderr, "\nThis option is currently unsupported on your system.\n");
117     return -1;
118 #endif
119   }
120
121   while (offset < argc-1 && !end_common_opts) {    /* Common options */
122     if (!strcmp(argv[offset+1], "--title")) {
123       if (argc-offset < 3 || title != NULL) {    /* No two "--title" please! */
124         Usage(argv[0]);
125         exit(-1);
126       }
127       else {
128         title = argv[offset+2];
129         offset += 2;
130       }
131     }
132     else if (!strcmp(argv[offset+1], "--hline")) {
133       if (argc-offset < 3 || hline != NULL) {    /* No two "--hline" please! */
134         Usage(argv[0]);
135         exit(-1);
136       }
137       else {
138         hline = argv[offset+2];
139         use_helpline(hline);
140         offset += 2;
141       }
142     }
143     else if (!strcmp(argv[offset+1], "--hfile")) {
144       if (argc-offset < 3 || hfile != NULL) {    /* No two "--hfile" please! */
145         Usage(argv[0]);
146         exit(-1);
147       }
148       else {
149         hfile = argv[offset+2];
150         use_helpfile(hfile);
151         offset += 2;
152       }
153     }
154     else if (!strcmp(argv[offset+1], "--clear")) {
155       if (clear_screen) {    /* Hey, "--clear" can't appear twice! */
156         Usage(argv[0]);
157         exit(-1);
158       }
159       else if (argc == 2) {    /* we only want to clear the screen */
160         init_dialog();
161         dialog_update();    /* init_dialog() will clear the screen for us */
162         end_dialog();
163         return 0;
164       }
165       else {
166         clear_screen = 1;
167         offset++;
168       }
169     }
170     else    /* no more common options */
171       end_common_opts = 1;
172   }
173
174   if (argc-1 == offset) {    /* no more options */
175     Usage(argv[0]);
176     exit(-1);
177   }
178
179   /* Box options */
180
181   if (!strcmp(argv[offset+1], "--yesno")) {
182     if (argc-offset != 5) {
183       Usage(argv[0]);
184       exit(-1);
185     }
186     init_dialog();
187     retval = dialog_yesno(title, argv[offset+2], atoi(argv[offset+3]),
188                           atoi(argv[offset+4]));
189
190     dialog_update();
191     if (clear_screen)    /* clear screen before exit */
192       dialog_clear();
193     end_dialog();
194     return retval;
195   }
196   else if (!strcmp(argv[offset+1], "--msgbox")) {
197     if (argc-offset != 5) {
198       Usage(argv[0]);
199       exit(-1);
200     }
201     init_dialog();
202     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
203                            atoi(argv[offset+4]), 1);
204
205     dialog_update();
206     if (clear_screen)   /* clear screen before exit */
207       dialog_clear();
208     end_dialog();
209     return retval;
210   }
211   else if (!strcmp(argv[offset+1], "--prgbox")) {
212     if (argc-offset != 5) {
213       Usage(argv[0]);
214       exit(-1);
215     }
216     init_dialog();
217     retval = dialog_prgbox(title, argv[offset+2], atoi(argv[offset+3]),
218                            atoi(argv[offset+4]), TRUE, TRUE);
219
220     dialog_update();
221     if (clear_screen)   /* clear screen before exit */
222       dialog_clear();
223     end_dialog();
224     return WEXITSTATUS(retval);
225   }
226   else if (!strcmp(argv[offset+1], "--infobox")) {
227     if (argc-offset != 5) {
228       Usage(argv[0]);
229       exit(-1);
230     }
231     init_dialog();
232     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
233                            atoi(argv[offset+4]), 0);
234
235     dialog_update();
236     if (clear_screen)   /* clear screen before exit */
237       dialog_clear();
238     end_dialog();
239     return retval;
240   }
241   else if (!strcmp(argv[offset+1], "--textbox")) {
242     if (argc-offset != 5) {
243       Usage(argv[0]);
244       exit(-1);
245     }
246     init_dialog();
247     retval = dialog_textbox(title, argv[offset+2], atoi(argv[offset+3]),
248                             atoi(argv[offset+4]));
249
250     dialog_update();
251     if (clear_screen)   /* clear screen before exit */
252       dialog_clear();
253     end_dialog();
254     return retval;
255   }
256   else if (!strcmp(argv[offset+1], "--menu")) {
257     if (argc-offset < 8 || ((argc-offset) % 2)) {
258       Usage(argv[0]);
259       exit(-1);
260     }
261     init_dialog();
262     retval = dialog_menu(title, argv[offset+2], atoi(argv[offset+3]),
263                          atoi(argv[offset+4]), atoi(argv[offset+5]),
264                          (argc-offset-6)/2, argv+offset + 6, result,
265                          NULL, NULL);
266     dialog_update();
267     if (retval == 0)
268         fputs(result, stderr);
269     if (clear_screen)   /* clear screen before exit */
270       dialog_clear();
271     end_dialog();
272     return retval;
273   }
274   else if (!strcmp(argv[offset+1], "--checklist")) {
275     if (argc-offset < 9 || ((argc-offset-6) % 3)) {
276       Usage(argv[0]);
277       exit(-1);
278     }
279     init_dialog();
280     retval = dialog_checklist(title, argv[offset+2], atoi(argv[offset+3]),
281                               atoi(argv[offset+4]), atoi(argv[offset+5]),
282                               (argc-offset-6)/3, argv+offset + 6, result);
283
284     dialog_update();
285     if (retval == 0) {
286       unsigned char *s, *h; int first;
287
288       h = result;
289       first = 1;
290       while ((s = strchr(h, '\n')) != NULL) {
291         *s++ = '\0';
292         if (!first)
293           fputc(' ', stderr);
294         else
295           first = 0;
296         fprintf(stderr, "\"%s\"", h);
297         h = s;
298       }
299     }
300     if (clear_screen)   /* clear screen before exit */
301       dialog_clear();
302     end_dialog();
303     return retval;
304   }
305   else if (!strcmp(argv[offset+1], "--radiolist")) {
306     if (argc-offset < 9 || ((argc-offset-6) % 3)) {
307       Usage(argv[0]);
308       exit(-1);
309     }
310     init_dialog();
311     retval = dialog_radiolist(title, argv[offset+2], atoi(argv[offset+3]),
312                               atoi(argv[offset+4]), atoi(argv[offset+5]),
313                               (argc-offset-6)/3, argv+offset + 6, result);
314
315     dialog_update();
316     if (retval == 0)
317         fputs(result, stderr);
318     if (clear_screen)   /* clear screen before exit */
319       dialog_clear();
320     end_dialog();
321     return retval;
322   }
323   else if (!strcmp(argv[offset+1], "--inputbox")) {
324     if (argc-offset != 5 && argc-offset != 6) {
325       Usage(argv[0]);
326       exit(-1);
327     }
328     if (argc-offset == 6)
329       strcpy(result, argv[offset+5]);
330     else
331       *result = '\0';
332     init_dialog();
333     retval = dialog_inputbox(title, argv[offset+2], atoi(argv[offset+3]),
334                              atoi(argv[offset+4]), result);
335
336     dialog_update();
337     if (retval == 0)
338         fputs(result, stderr);
339     if (clear_screen)   /* clear screen before exit */
340       dialog_clear();
341     end_dialog();
342     return retval;
343   }
344 /* ftree and tree options */
345   else if (!strcmp(argv[offset+1], "--ftree")) {
346         unsigned char *tresult;
347     if (argc-offset != 8) {
348       Usage(argv[0]);
349       exit(-1);
350     }
351     init_dialog();
352     retval = dialog_ftree(argv[offset+2], *argv[offset+3],
353         title, argv[offset+4], atoi(argv[offset+5]), atoi(argv[offset+6]),
354                             atoi(argv[offset+7]), &tresult);
355
356     dialog_update();
357     if (!retval)
358     {
359         fputs(tresult, stderr);
360         free(tresult);
361     }
362     if (clear_screen)   /* clear screen before exit */
363       dialog_clear();
364     end_dialog();
365     return retval;
366   }  
367   else if (!strcmp(argv[offset+1], "--tree")) {
368         unsigned char *tresult;
369     if (argc-offset < 8) {
370       Usage(argv[0]);
371       exit(-1);
372     }
373     init_dialog();
374     retval = dialog_tree((unsigned char **)argv+offset+7, argc-offset-7,
375         *argv[offset+2], title, argv[offset+3], atoi(argv[offset+4]),
376         atoi(argv[offset+5]), atoi(argv[offset+6]), &tresult);
377
378     dialog_update();
379     if (!retval)
380         fputs(tresult, stderr);
381
382     if (clear_screen)   /* clear screen before exit */
383       dialog_clear();
384     end_dialog();
385     return retval;
386   }    
387
388   Usage(argv[0]);
389   exit(-1);
390 }
391 /* End of main() */
392
393
394 /*
395  * Print program usage
396  */
397 void Usage(char *name)
398 {
399   fprintf(stderr, "\
400 \ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\
401 \n  patched to version %s by Stuart Herbert (S.Herbert@shef.ac.uk)\
402 \n  Changes Copyright (C) 1995 by Andrey A. Chernov, Moscow, Russia\
403 \n  patched by Anatoly A. Orehovsky (tolik@mpeks.tomsk.su)\
404 \n\
405 \n* Display dialog boxes from shell scripts *\
406 \n\
407 \nUsage: %s --clear\
408 \n       %s --create-rc <file>\
409 \n       %s [--title <title>] [--clear] [--hline <line>] [--hfile <file>]\\\
410 \n              <Box options>\
411 \n\
412 \nBox options:\
413 \n\
414 \n  --yesno     <text> <height> <width>\
415 \n  --msgbox    <text> <height> <width>\
416 \n  --prgbox    \"<command line>\" <height> <width>\
417 \n  --infobox   <text> <height> <width>\
418 \n  --inputbox  <text> <height> <width> [<init string>]\
419 \n  --textbox   <file> <height> <width>\
420 \n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
421 \n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
422 \n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
423 \n  --ftree     <file> <FS> <text> <height> <width> <menu height>\
424 \n  --tree      <FS> <text> <height> <width> <menu height> <item1>...\n", VERSION, name, name, name);
425 }
426 /* End of Usage() */