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