File: intro.help

package info (click to toggle)
linuxconf 1.26r4-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 56,432 kB
  • ctags: 27,217
  • sloc: cpp: 158,803; perl: 7,484; sh: 4,134; java: 3,105; ansic: 2,492; makefile: 2,216; python: 109
file content (1386 lines) | stat: -rw-r--r-- 42,985 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
  shellmod
  Introduction


  11..  WWhhaatt iiss sshheellllmmoodd

  Shellmod is a Linuxconf module as well as a stand-alone utility.  Its
  goal is to allow easy writing of other Linuxconf modules and stand-
  alone utilities using sh (/bin/sh, the shell interpretor).

  The benefit of writing Linuxconf modules (or simply administration
  utilities) this way are:


  +o  Nice interface: Your script will work both in text and graphical
     mode, with a much better appearance than an usual shell script.
     When used as a module in Linuxconf, it will even work in HTML,
     completely transparently.

  +o  Simplicity: It is possible to write useful stuff in a 10-15 lines
     shell script. It is possible to turn an non interactive existing
     10-15 lines shell script into a 15-20 lines cool interactive
     script, running     both in text, GUI mode, and even HTML mode.

  +o  Used as a module, your script will be able to hook itself in
     various Linuxconf menus, making it fully integrated in the
     administration scheme.

  +o  Not only the script can enhance Linuxconf menus, it can even
     participate as a co-manager in some dialogs. This means that a
     simple script can add new fields in the user account dialog for
     example.

  Normal C++ Linuxconf module can do more things obviously, but scripts
  offers a nice and efficient solution for custom installation and on
  site support. A new Linuxconf module may be develop with the
  user/friend/customer looking over your shoulder.


  22..  PPrriinncciipplleess

  In this section we will see the basic layout of a shellmod script, how
  to use it and how it communicate with Linuxconf.


  22..11..  CCoommppoonneennttss ooff tthhee sshheellllmmoodd ppaacckkaaggee

  The shellmod package provides the following parts:


  +o  The shellmod utility used to run shellmod script without Linuxconf.
     This utility is located in /usr/bin.

  +o  The shellmod module which allows shellmod script to interact with
     Linuxconf. Note that a shellmod script can be used both ways,
     either stand-alone or embedded in Linuxconf.

  +o  The shellmod-lib.sh function library. This is located in
     /usr/lib/linuxconf/lib. This contains utility functions simplifying
     shellmod scripts. This file must be sourced in all scripts.

  +o  Some sample script.

  +o  At some point, the package will contain some contrib scripts and a
     browser will be designed to easily find and try those contrib
     scripts. If you have written something general and useful, send it
     on the Linuxconf mailing list, for inclusion in this package.


  22..22..  HHooww ttoo uussee sshheellllmmoodd ssccrriippttss

  A script may be used either stand-alone or within Linuxconf. It can be
  used both ways.


  22..22..11..  AAss aa ssttaanndd--aalloonnee uuttiilliittyy

  To run a shellmod script, you either do



               shellmod path_of_the_script [ arguments ]





  Or if the script start with #!/usr/bin/shellmod, you simply run it
  like any utility. Note that in all cases, the script must be
  executable (chmod +x script).


  22..22..22..  AAss aa LLiinnuuxxccoonnff mmoodduullee

  To be used this way, it must be registered in Linuxconf. This is done
  either interactively or using a special command line. The shellmod
  module register its configuration menu in the Control files and
  systems menu. You will find there a dialog to register your script.
  Just enter the path of your script and that's it. The script will be
  visible in Linuxconf at the next run.

  The script may be registered using the following command line. This is
  especially useful if you include your script in a package and would
  like to register the script in Linuxconf at package installation (RPM
  packagers might consider the trigger facility to do this).



               linuxconf --modulemain shellmod --setmod script_path





  Note that the linuxconf --modulemain construct is the normal way to
  yield control to a module own command line: shellmod is not different.

  You may unregister a script from Linuxconf by doing:



               linuxconf --modulemain shellmod --unsetmod script_path





  Note that the above syntax replicate the way normal (C++) Linuxconf
  modules may be registered and unregistered, by using the linuxconf
  --setmod and linuxconf --unsetmod command lines.


  22..22..33..  AAss aann iinnddeeppeennddaanntt ssccrriipptt,, iinn lliinnuuxxccoonnff ccoonntteexxtt

  This is almost equivalent to the standalone mode, except that
  linuxconf and all its modules are listening. This mode is necessary if
  your script uses the virtual registry: Linuxconf and its modules have
  to be alived to react properly.



               linuxconf --modulemain shellmod --exec script_path \
                       [--debug] [--perl] script arguments






  22..33..  LLaayyoouutt ooff aa sshheellllmmoodd ssccrriipptt

  A shellmod script will always look like this:



               #!/usr/bin/shellmod
               . /usr/lib/linuxconf/lib/shellmod-lib.sh
               register(){
                       # Put regmenu and comanager calls here
               }
               # Put here the various functions referenced above

               main(){
                       # We define a sub-menu or a dialog
               }
               # The script always end with the dispatch function call. Always
               dispatch






  22..33..11..  TThhee sshheellllmmoodd--lliibb..sshh ffuunnccttiioonn lliibbrraarryy


  22..33..22..  TThhee rreeggiisstteerr ffuunnccttiioonn

  The register function is required if the script is used as a Linuxconf
  module. Linuxconf will call the function expecting the script to pass
  back the list of menu and dialog in which it want to register. Here is
  an example of a register function installing two sub-menu and one co-
  manager.



               # Register in the "miscellaneous service" menu
               echo regmenu main MENU_MISCSERV \"main menu of the module\"
               # Register at the end of the dnsconf menu
               echo regmenu function2 dnsconf \"Some title\"
               # Register as a co-manager in the user account dialog
               echo comanager function-prefix user






  22..33..33..  TThhee rreeggiisstteerr ffuunnccttiioonn ffoorr ssttaanndd--aalloonnee oonnllyy mmoodduullee

  The register function is not needed for stand-alone module. It is a
  good idea to provide a minimal one in case a user try to register this
  module in Linuxconf. The following one will make it clear the script
  is not intended to be use this way:



               register(){
                       echo error \"This shellmod script can't be use as a module\"
               }






  22..33..44..  TThhee mmaaiinn ffuunnccttiioonn

  If the script is used stand-alone, it requires a function called main.
  The shellmod utility will blindly call this function.  It is a good
  idea to always provide one. In the register function we often register
  in a Linuxconf menu the main function. Done this way, the script
  provides a consistent interface used either stand-alone or as a
  Linuxconf module.

  The main function will generally define a menu or a dialog. Note that
  the main function is the one which will receive the script arguments.
  The arguments will often be used as default values for the dialog
  fields.  Here is a small example.



               main(){
                       echo DIALOG
                       echo newf_str path \"Document path\" $1
                       echo newf_str mail \"Email this document to\" $2
                       echo newf_str fax \"Fax this document to\" $3
                       echo edit \"Document manager\" \"Fill this form to send the document\"
                       dispatch
                       echo end
                       if [ "$CODE" = "accept" ] ; then
                               if [ "$mail" != "" ] ; then
                                       cat $path | mail $mail
                               fi
                               if [ "$fax" != "" ] ; then
                                       spoolfax $fax $path
                               fi
                       fi
               }






  22..33..55..  TThhee ddiissppaattcchh ffuunnccttiioonn

  A module always ends with a call to the dispatch function. A shellmod
  script may be seen as a set of function waiting to be called (A
  library).  Based on context, Linuxconf (or shellmod for stand-alone
  scripts) will call the appropriate one.

  Note that the script can perform some initialization before calling
  the dispatch function. As explain later, a script may be seen as a
  small server which keeps its state between calls to its various
  functions.


  22..44..  HHooww ddooeess iitt wwoorrkkss

  A shellmod script interact with shellmod or Linuxconf by echoing
  commands on it standard output. It receives directives by simply
  reading its standard input. The dispatch function takes care of
  reading and processing (dispatching) the request it receives.  We can
  think of the script as being in sandwich between two shellmod process
  like this



               shellmod | script | shellmod





  Everything echoed by the script is grabbed by shellmod and interpreted
  as protocol commands. It is important to redirect the output of sub-
  command you are using either to the error channel (command >&2) or to
  /dev/null. Failing to do so will trigger many error messages from
  shellmod.


  33..  PPrroottooccooll

  we will now present the various commands issued by the script. Those
  commands will be split by task


  33..11..  CCoommmmaanndd llaayyoouutt aanndd qquuoottiinngg

  All command sent to shellmod are done using the echo shell command.
  They always looks like:



               echo command arg1 arg2 arg3





  Arguments are either a single or multiple words (separated with
  spaces).  To group multiple words as a single argument, quotes must be
  used.  While this is standard command line practice, there is a catch:
  Quoting will only affect the argument as seen by the echo command.
  Once process, the whole line will be received as a single stream of
  words separated by space and the quote will be gone. The quotes must
  be part of the line received by shellmod. Here is an example



               echo newf_str name \"Enter your name\" \"Tux the penguin\"





  The shellmod-lib.sh define the qecho helper function you may used to
  get a more standard shell quoting behavior. Here the same example
  rewritten with qecho.
               qecho newf_str name "Enter your name" 'Tux the penguin'





  As you see, with qecho you can mix the different shell quoting syntax.
  The qecho function insures that proper double quotes surround all
  arguments.



  33..22..  SSeennddiinngg mmuullttii--lliinnee ppaarraammeetteerrss

  Shell scripts are not that good at handling and passing multi-line
  text. The "defval" command was created to fix that.  Here is a typical
  usage:



               echo var1 "This is the first line"
               echo var1 "This is the second line"
               echo error =var1





  This creates a popup error message with two lines. "defval" is used
  repeatedly to define the multi-line text and is referenced as an
  argument using the = sign. The argument must not be quoted. So you
  can't use the qecho helper function using a defvar parameter, because
  qecho insures quoting around all parameters.


  33..33..  BBuuiillddiinngg aa ddiiaalloogg



  33..33..11..  eecchhoo DDIIAALLOOGG

  A dialog always starts with this command. It requires no further
  argument.  Then you stuff it with field definitions, add optional
  buttons and then you call the edit function. Here is a sample:



               echo DIALOG
               echo newf_str var \"field title\" value
               edho edit \"Dialog title\" \"Dialog introduction\"
               dispatch
               echo end






  33..33..22..  eecchhoo sseettttyyppee DDIIAATTYYPPEE__PPOOPPUUPP

  This requires the window manager to present this dialog as an
  independant window in the middle of the screen. This is usually used
  for transient dialog requiring immediate attention from the user.



  33..33..33..  eecchhoo eeddiitt \\""ttiittllee\\"" \\""IInnttrroodduuccttiioonn\\"" [[ \\""bbuuttttoonn,,bbuuttttoonn,,......\\"" ]]

  This pops up the dialog. The window title control using the first
  argument and the longer dialog description is controlled by the
  introduction field.

  The last argument is option and lets you control the buttons displayed
  at the bottom of the dialog. The value "0" means to display no button
  (useful to display some gauge for example).

  When the last argument is omitted, the button Accept and Cancel are
  displayed.


  33..33..44..  eecchhoo sshhooww \\""ttiittllee\\"" \\""IInnttrroodduuccttiioonn\\""

  This works like edit. It pops up the dialog with the same arguments.
  But it return immediatly. This is generally used with the
  ``newf_gauge'' command.


  33..33..55..  ddiissppaattcchh

  This yield control to Linuxconf/shellmod and wait for results.  Field
  variable are updated and the CODE variable is set to the button value
  selected by the user: This is either "accept" or "cancel".


  33..33..66..  eecchhoo eenndd

  This deletes the dialog. It is removed from the screen and forgotten.
  We often issue the end command right after the dispatch command. But
  more complex dialog may use the end command after a validation loop.


  33..33..77..  AA ccoommpplleettee eexxaammppllee



       #!/usr/bin/shellmod
       . /usr/lib/linuxconf/lib/shellmod-lib.sh
       main(){
               echo DIALOG
               echo newf_str name \"User name\"
               while true
               do
                       echo edit \"User query\" \"Enter the user name\"
                       dispatch
                       if [ "$CODE" = "cancel" ] ; then
                               break
                       elif [ "$name" = "" ] ; then
                               echo error \"Please provide a name\"
                       else
                               echo notice \"Doing something with the user account\"
                               break
                       fi
               done
               echo end
       }
       dispatch






  33..44..  BBuuiillddiinngg aa mmeennuu

  This is handled by the DIALOG_MENU and new_menuitem commands.


  33..44..11..  eecchhoo DDIIAALLOOGG__MMEENNUU

  This does not require any argument.


  33..44..22..  eecchhoo nneeww__mmeennuuiitteemm ffuunnccttiioonn pprroommpptt ttiittllee

  This records one menu entry. Each menu entry is associated with one
  script function (that must be defined). The prompt is generally a
  keyword. The title is the rest of the menu entry.


  33..44..33..  eecchhoo eeddiittmmeennuu \\""MMeennuu ttiittllee\\"" \\""IInnttrroodduuccttiioonn\\""

  This pops the menu. It is followed by a call to dispatch.


  33..44..44..  ddiissppaattcchh

  This is where everything is done for a menu. The dispatch function
  will run until the user select the "quit" button.  The corrresponding
  function is called whenever a menu entry is selected. This is handled
  transparently by the dispatch function.

  Note that the dispatch function also exits if the user select an
  optional buttons (added with the button command).  So it is possible
  to handle a in a loop like the example dialog above.


  33..44..55..  eecchhoo eenndd

  This deletes the menu.


  33..44..66..  AA ccoommpplleettee eexxaammppllee



       #!/usr/bin/shellmod
       . /usr/lib/linuxconf/lib/shellmod-lib.sh
       menufunc1(){
               echo notice \"menufunc1 selected\"
       }
       menufunc2(){
               echo notice \"menufunc2 selected\"
       }
       main(){
               echo DIALOG_MENU
               echo new_menuitem menufunc1 Select \"First option\"
               echo new_menuitem menufunc2 \"\" \"Second option\"
               echo editmenu \"Main menu\" \"Pick an option\"
               dispatch
               echo end
       }
       dispatch






  33..55..  MMaannaaggiinngg aa lliisstt ooff rreeccoorrddss


  33..55..11..  eecchhoo DDIIAALLOOGG__LLIISSTT

  A DIALOG_LIST is just a variation of a menu. The main difference is
  that the number of entry might be very long. In that case a filter
  dialog will popup so restrict the amount of diaplayed record. You can
  deal with very large list of item.

  DIALOG_LIST does not require any argument.


  33..55..22..  eecchhoo nneewwff__hheeaadd \\""CCoolluummnn11 ttiittllee\\"" \\""CCoolluummnn22 ttiittllee\\"" ......

  You can define the heading of the list. This is optional, but looks
  much more nicer.


  33..55..33..  eecchhoo nneeww__mmeennuuiitteemm \\""ffuunnccttiioonn aarrggss\\"" \\""CCoolluummnn11 vvaalluuee\\"" \\""CCooll--
  uummnn22 vvaalluuee\\"" ......

  It works like DIALOG_MENU, except that we often supply more columns.
  There is another variation as the function is defined with arguments.
  Note that this may be used with DIALOG_MENU as well. We generally
  define one function per menu entry and a single function to process
  each record of the list, using the argument to differentiate the
  processing.

  Note also that you can use a mixed solution within the same
  DIALOG_MENU or DIALOG_LIST: You can use a single function to provide a
  common processing for some record and different function to manage
  exception.


  33..55..44..  eecchhoo eeddiittmmeennuu \\""LLiisstt ttiittllee\\"" \\""IInnttrroodduuccttiioonn\\""

  Same as with DIALOG_MENU.


  33..55..55..  ddiissppaattcchh

  This behave like the DIALOG_MENU.


  33..55..66..  eecchhoo eenndd

  This delete the list.


  33..55..77..  AA ccoommpplleettee eexxaammppllee

  Here is a realistic example where we display a directory and let the
  user pick one file and do something with it.  We see in this example
  how easy it is to parse the output of the "ls -l" command and present
  the file name, the size and revision date in three formatted column.










  #!/usr/bin/shellmod
  . /usr/lib/linuxconf/lib/shellmod-lib.sh
  fileshow(){
          echo notice \"Processing file $1\"
  }
  main(){
          echo DIALOG_LIST
          echo newf_head \"File name\" Sise \"Revision date\"
          ls -l $1 | \
                  (
                  read total
                  while read perm count user group size month day hour name
                  do
                          echo new_menuitem \"fileshow $name\" $name $size \"$month $day $hour\"
                  done
                  )
          echo editmenu \"Current directory\" \"This show all file in the current directory\"
          dispatch
          echo end
  }
  dispatch





  33..66..  DDeeffiinniinngg ffiieellddss

  All commands defining a dialog field start with the prefix newf_.  We
  have used the same name and same parameter order (when possible) as
  the C++ module API.

  The first argument is always the name of the shell variable which will
  receive the value entered by the user. You will often use the
  following construct to edit (correct the current value) of a given
  variable.



               qecho newf_str var "title" "$var"
               .
               qecho edit ...
               dispatch
               if [ "$CODE" = "accept" ] ; then
                       if [ "$var" = "..." ] ;then
                               .
                               .
                       fi
               fi






  33..77..  CCoommmmaanndd lliisstt

  Here is the list of all field definition commands:


  +o  ``newf_chk''

  +o  ``newf_chkm''

  +o  ``newf_combo''

  +o  ``newf_dbl''

  +o  ``newf_enum''

  +o  ``newf_gauge''

  +o  ``newf_hexnum''

  +o  ``newf_list''

  +o  ``newf_num''

  +o  ``newf_pass''

  +o  ``newf_radio''

  +o  ``newf_slider''

  +o  ``newf_str''

  +o  ``newf_title''




  33..77..11..

  eecchhoo nneewwff__cchhkk vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall 00 oorr 11 vvaalluuee\\"" \\""SSuuffffiixx
  ttiittllee\\""

  Setup a check box field (on/off or yes/no). The variable var will be
  setup to either 0 or 1. This field has two title. One on the left of
  the check box and one on the right. This is often used like this in
  Linuxconf:



               The current feature [ ] is selected






  33..77..22..  VVaarriiaattiioonn ooff tthhee nneewwff__cchhkk ssyynnttaaxx

  When using newf_chk, you must pass a 0 or 1 as the value. The edit
  variable will receive the result as 0 or 1. This is not so useful as
  often shell script are dealing with different type of boolean value.
  For example, a script dealing with an SQL server may find itself
  dealing with Y and N values. To avoid translating from one system to
  the other, the syntax of the initial value has been expanded.


  +o  To make things easy, shellmod will accept as a selected value
     anything in 1,Y and Yes (case insensitive). Unless told
     differently, these values will be translated to 1. Anything else
     will be translated to 0.

  +o  By using a special triplet format, one can specify the actual value
     and the dictionary used to interpret it. You specify the value like
     this:




                  value:on_value:off_value






  So if you application is dealing with ON/OFF values, you can specify
  the initial value like this:



                       $var:ON:OFF






  Not only ON and OFF will be accepted to interpret the value, but the
  end result will be sent to the script using one of those word.


  33..77..33..

  eecchhoo nneewwff__cchhkkmm vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall nnuummeerriicc vvaalluuee\\""
  \\""vvaalluuee11\\"" \\""vvaalluuee22\\"" ......

  Setup of multiple selection field using check boxes. The boxes are
  presented horizontally. Here is an example followed with the field it
  produced in text mode:



               echo newf_chkm sel \"Which position\" 1 left center right





  This produces:



               Which position    ( ) left  (o) center ( ) right





  The variable var will take the numerical index of the selected item,
  starting at 0.


  33..77..44..

  eecchhoo nneewwff__ccoommbboo vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall vvaalluuee\\""

  Setup a single line + selector field. The user will be able to pick a
  value out of a pick list or enter another by hand. The variable var
  will contain the textual value either entered or selected.

  newf_combo is used with the comboitem command. You setup first the
  combo field and then you pass one by one the possible values using
  comboitem. Note that the values are followed by a descriptive text
  (optional). Here is a code sample:
               echo newf_combo port \"Which port\" ttyS1
               echo comboitem ttyS0 \"COM1 in DOS\"
               echo comboitem ttyS1 \"COM2 in DOS\"
               echo comboitem ttyS2 \"COM3 in DOS\"





  The variable $port will take the value ttyS0, ttyS1, ttyS2 or anything
  the user dares to enter. See ``newf_enum'' and ``newf_list'' for a
  variation of this input field.


  33..77..55..

  eecchhoo nneewwff__ddbbll vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall nnuummeerriicc vvaalluuee\\"" nnuummbbeerr--ooff--
  ddeecciimmaall

  Setup a numerical input field with decimal notation. Works like
  ``newf_num'' except that a decimal point is allowed. The number of
  decimal parameter control the number of digits allowed after the
  decimal point as well as the formatting of the field.


  33..77..66..

  eecchhoo nneewwff__eennuumm vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall nnuummeerriicc vvaalluuee\\""

  Setup a selector field. The user will be able to pick a value out of a
  pick list. The variable var will contain the index of the selected
  item. The user is limited to picking one item of the list.

  newf_enum is used with the enumitem command. You setup first the enum
  field and then you pass one by one the possible values using enumitem.
  Here is a code sample:



               echo newf_enum no \"Which port\" 1
               echo enumitem ttyS0 \"COM1 in DOS\"
               echo enumitem ttyS1 \"COM2 in DOS\"
               echo enumitem ttyS2 \"COM3 in DOS\"





  The variable $no will take the value 0 1 or 2. See ``newf_combo'' and
  ``newf_list'' for a variation of this input field.


  33..77..77..

  eecchhoo nneewwff__ggaauuggee IIDD \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall ddeecciimmaall vvaalluuee\\"" \\""MMaaxxiimmuumm
  vvaalluuee\\""

  Setup a visual gauge, generally used to display the completion status
  of a process (loading, installing). The state of the gauge is changed
  by calling this command again. The first call defines the field, the
  next ones update the gauge. This widget is generally used with the
  "show" command so the script never stop in the "edit" state. Here is a
  small example



          echo DIALOG
          qecho newf_gauge ID "Status" 0 10
          qecho show "Status" ""
          i=0
          while [ "$i" != "10" ] ; do
              i=`expr $i + 1`
              sleep 1
              qecho newf_gauge ID "Status" $i 10
              qecho show "Status" ""
          done






  33..77..88..

  eecchhoo nneewwff__hheexxnnuumm vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall hheexxaa--ddeecciimmaall vvaalluuee\\""

  Setup a numerical input field (integer). Works like ``newf_num'' but
  accept digits and hexa-decimal digits.


  33..77..99..

  eecchhoo nneewwff__lliisstt vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall vvaalluuee\\""

  Setup a selector field. The user will be able to pick a value out of a
  pick list only The variable var will contain the textual value
  selected.

  newf_list is used with the listitem command. You setup first the list
  field and then you pass one by one the possible values using listitem.
  Note that the values are followed by a descriptive text (optional).
  Here is a code sample:



               echo newf_list port \"Which port\" ttyS1
               echo listitem ttyS0 \"COM1 in DOS\"
               echo listitem ttyS1 \"COM2 in DOS\"
               echo listitem ttyS2 \"COM3 in DOS\"





  The variable $port will take the value ttyS0, ttyS1 or ttyS2.  See
  ``newf_enum'' and ``newf_combo'' for a variation of this input field.


  33..77..1100..

  eecchhoo nneewwff__nnuumm vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall nnuummeerriicc vvaalluuee\\""

  Setup a numerical input field (integer). Works like newf_str but
  accept only digit.


  33..77..1111..

  eecchhoo nneewwff__ppaassss vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall vvaalluuee\\""

  Setup a password field. Works like a newf_str field except the input
  is not echoed (invisible typing).
  33..77..1122..

  eecchhoo nneewwff__rraaddiioo vvaarr \\""ffiieelldd ttiittllee\\"" nnuummeerriicc--vvaalluuee iinnssttaannccee--vvaalluuee
  \\""ssuuffffiixx ttiittllee\\""

  Setup a radio button field. Several radio button fields must be
  defined for each possible selection. All radio buttons sharing the
  same input variable (var above) operate together: Selecting one De-
  select the other. The var variable will get the numeric-value of the
  selected radio button field.

  Related radio buttons may be placed anywhere in a dialog. They do not
  have to be sequential or even on the same page of the notebook dialog


  33..77..1133..

  eecchhoo nneewwff__sslliiddeerr vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall ddeecciimmaall vvaalluuee\\"" \\""mmiinnii--
  mmuumm vvaalluuee\\"" \\""MMaaxxiimmuumm vvaalluuee\\""

  This works like the newf_num, to edit a decimal value. But it is shown
  as a visual slider. The minimum and maximum value represent the left
  and right edge of the slider.



               qecho newf_slider var "Meeting hour" 15 9 16






  33..77..1144..

  eecchhoo nneewwff__ssttrr vvaarr \\""ffiieelldd ttiittllee\\"" \\""IInniittiiaall vvaalluuee\\""

  Setup a one line text input.


  33..77..1155..

  eecchhoo nneewwff__ttiittllee ""PPaadd ttiittllee"" lleevveell ""LLeefftt ttiittllee"" ""TTeexxtt mmooddee ttiittllee""

  This is not an input field but a way to organize a large dialog in
  section. The end result is far different in graphic mode than in text
  or HTML mode. In graphic mode, this will create a notebook dialog and
  each newf_title defines one page (one pad) of the notebook.

  The first argument, pad title, is only used in graphic mode.

  The     second argument is a number and represent the notebook level.
  This allows very complex dialogs with notebook within notebook. In
  text and HTML mode, this argument has no effect.


  +o  A value of 0 add an horizontal splitter between two fields. The
     "Text mode title" is centered in that splitter.

  +o  A value of 1 create the first level of notebook. A value of 2
     create a sub-notebook with the current one.

  The third argument, left title, is used only in text and HTML mode.
  It places a small title on the left of the input fields.


  The last argument, text mode title, appears centered between two input
  fields.


  33..88..  AAddddiinngg bbuuttttoonnss

  You can add optional buttons simply by using the button command. It
  requires to arguments. The first is the button ID which will be passed
  to the script using the CODE variable. The second is the label (title)
  of the button. Here is an example:



               echo DIALOG
               echo newf_str name \"User name\" $name
               echo button Add \"Add a new user\"
               echo edit "title" \"User management\"
               dispatch
               echo end
               if [ "$CODE" = "Add" ] ; then
                       # Adding a new user
               elif [ "$CODE" = "accept" ] ; then
                       # Inspecting a user record
               fi






  33..99..  SSeett tthhee ccuurrrreenntt iinnppuutt ffiieelldd

  The "setcurfield" opcode sets the keyboard focus on a specific field.
  You must pass the field ID as a single argument. Here is an example:



               qecho DIALOG
               qecho newf_str uid "User id"
               qecho newf_str name "Name"
               qecho newf_str phone "Name"
               qecho setcurfield name
               qecho edit "sample" "The focus is now on name"
               dispatch
               echo end






  33..1100..  MMiisscceellllaanneeoouuss


  33..1100..11..  eecchhoo rreemmoovvee__aallll

  Remove all fields from a dialog, allowing you to redefine its content.



  44..  BBuuiillddiinngg ccoo--mmaannaaggeerrss

  Co-managers are exciting. They allows one to add functionalities to
  Linuxconf right where it belongs, instead of adding new sub-menus.


  44..11..  PPrriinncciipplleess

  A co-manager is a component that participate in a dialog. It may add
  fields and validation. The most common case is the user account
  dialog, where several co-managers participate. The most visible one is
  the mailconf module, which insert a complete section to handle email
  aliases. Another is the pppdialin module which add a section to deal
  with PPP parameters.

  A co-manager must provide 4 functions:


  +o  Adding fields to the dialog. Here the co-manager will probably add
     a new section and few fields. It is not forced to add anything.

  +o  Add validation. The co-manager may do all kind of validation not
     only on its own fields. The admin is not allowed to commit any
     changes to the user account until all co-managers agree.

  +o  Save the inputs. The co-manager must save the value of the fields
     it manages. User account co-managers have to preserver information
     on a per user basis.

  +o  Delete information associated to the user account/information
     record when it is deleted.

  Note that the co-managers have been created with user accounts in
  mind, but the concept is more general than that. Change "user account"
  above for "record" and you get a more general picture.


  44..22..  RReeggiisstteerriinngg tthhee ccoo--mmaannaaggeerr

  Linuxconf must be notified that a co-manager exists for a given
  dialog.  Dialogs are identified by a small key. For example, the key
  for the user account dialog is "user".

  A shellmod co-manager must provide four functions, using the same
  prefix.  When registering the co-manager, you provide the function
  prefix and the dialog key. This is done with in the register function
  Here is an example:



               # Register as a co-manager in the user account dialog
               echo comanager ufct user





  The function prefix is ufct. One must create four functions according
  to this prefix:


  +o  ufct-setupdia

  +o  ufct-validate

  +o  ufct-save

  +o  ufct-deluser




  44..33..  TThhee vvaarriioouuss ffuunnccttiioonnss


  44..33..11..  sseettuuppddiiaa

  This function is called when building the dialog. You can use any
  opcode normally used to define a dialog. You do not have to define the
  dialog yourself (echo DIALOG) as it is implicitly defined.

  While you can simply add fields in the dialog, one will generally
  define a new dialog section. Unless you do that, your new field will
  be appended in the current section, which can be any section.

  You define a section with the newf_title opcode



               qecho newf_title "Mailing lists" 1 - "Mailing lists"






  44..33..22..  vvaalliiddaattee

  This function receives all field value (entered by the user). Each
  field correspond to a shell variable, so you can test their value
  directly. You must use the "retcode" opcode to tell if the validation
  was successful. Here is an example



               echo retcode 0





  Any value different from 0 is taken as a validation failure. Any error
  must be reported with the "error" opcode. You may also use the
  "setcurfield" to jump to a specific field.



               if [ "$a1" = "valid" ] ; then
                       echo retcode 0
               else
                       echo setcurfield a1
                       echo retcode -1
                       echo error \"sample.sh: Invalid value, enter the word valid\"
               fi







  44..33..33..  ssaavvee

  All field's value are returned to your script as shell variable.  The
  save function must do various things with the information. It can
  either save it in a file, or perform some actions (send an email to an
  administrator about the required changes for example).

  Other shell variable also contain information related to this dialog
  (see dialog context below).


  44..33..44..  ddeelluusseerr

  This function name is a bit miss-leading. It means that the record
  must be deleted (in general, a user account). You must use the
  information from the dialog context (see below) to perform the
  required deletion.


  44..44..  DDiiaalloogg ccoonntteexxtt

  A co-manager is handling one part of a larger dialog. To properly
  manage its part, the co-manager must know other information about the
  current dialog. For example, to enhance the user account dialog, one
  must know the user account (user id) being edited as well as the
  domain (is it a virtual email domain user account ?).

  This extra infomation is passed as shell variable, so readily usable.
  The available information is dialog dependent. For user account co-
  managers, the following variables are provided:


     ddoommaaiinn
        The virtual email domain is passed. For the main domain, this
        variable is set to /.

     iiss__nneeww
        This is a flag telling you if this is a new account (name is
        empty) or not.

     nnaammee
        This is the user id.

  One way to learn the information available to your script is by
  running it in debug mode under Linuxconf. You enable this mode from
  Linuxconf user interface, in control file and system/shell module
  management/shellmod configuration.


  55..  UUssiinngg tthhee vviirrttuuaall rreeggiissttrryy

  The virtual registry is a general interface to get and set value from
  various modules in Linuxconf. You can learn more about it by reading
  the "manual" page for the vregistry module.

  We describe here how to use it from a shellmod script.


  55..11..  vvrreegg__sseett rreeggiissttrryy__vvaarriiaabbllee__nnaammee vvaalluuee

  You can set any variable by issuing the vreg_set command.  The
  variable name is one registry variable. You can learn the about the
  available variable by running /sbin/vregistry --list.

  You generally issue several vreg_set statements and then you call the
  vreg_do function to commit the request. The various modules are
  updated at this time only.






  55..22..  vvrreegg__ggeett rreeggiissttrryy__vvaarriiaabbllee__nnaammee sshheellll--vvaarriiaabbllee

  This will collect the value of the registry variable into a local
  variable of the shell named shell-variable.

  You generally issue several vreg_get statements and then you call the
  vreg_do function to commit the request. After having called vreg_do,
  your shell variables are properly assigned.



               qecho vreg_get samba.workgroup workgroup
               qecho vreg_get samba.winsserver wins
               # At this point, neither workgroup or wins are assigned
               vreg_do
               qecho notice "Your workgroup is $workgroup, wins server, $wins"






  55..33..  vvrreegg__ddoo

  vreg_do is a shell function. so you use it directly unlike most other
  shellmod command which are "echoed". vreg_do acts like the dispatch
  command. It requests action and grab the results.


  66..  SSccrriipptt pprroocceessss lliiffee

  Shellmod and Linuxconf will start the script whenever it is needed.
  Used as a Linuxconf module, the script is not started at Linuxconf
  startup but only when one of its menu or co-manager entries are
  selected.

  The script is start and proceed to its dispatch function, where it
  waits for request. Some request triggers the execution of one of the
  script's function. When the function done, the original dispatch
  function resume and continue to wait. Note that dispatch may be used
  recursively.

  Once started, the script sits there waiting for request until
  Linuxconf end. As such it can be seen as a small server sharing
  information collected while performing various request.

  When used as a stand-alone utility, the script will end as soon as its
  main function exits.


  77..  MMoodduullee bbuuiillddeerr

  A shell module builder is available to get you started faster.  You
  access this builder from shellmod main menu or with the shellmod
  utility:



               shellmod --build





  A single dialog appears. You fill it and this create the framework for
  a new shell module. Here are the various fields
  77..11..  PPaatthh ooff tthhee mmoodduullee

  You simply enter the full or relative path of the new shell script you
  want to create. The builder is not able to edit an existing module.


  77..22..  IInnsseerrtt iinn mmeennuu

  You must supply the menu id of the menu in which you want to insert
  the module (in Linuxconf). A module may insert in several Linuxconf
  menus, but the builder only supports one. Modifying the code later is
  easy.

  This field has a help list to pick the proper ID.


  77..33..  MMeennuu ttiittllee

  Just enter the text of the menu entry.


  77..44..  TThhiiss iiss aa uusseerr aaccccoouunntt ccoo--mmaannaaggeerr

  By selecting this check-box, you instruct the builder to generate the
  proper co-manager function templates (setupdia,save,deluser,validate).

  Note that a module may be a co-manager and insert in menus as well.


  77..55..  MMaaiinn mmeennuu eennttrriieess

  You simply enter the various menu entries. For each one, the builder
  will generate a shell function template menufunc1, menufunc2. It will
  also generate the menu code in the main function. You will have to
  provide the code for the various menufunc functions.