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