]> andersk Git - moira.git/blob - clients/moira/Doc/internal.mss
Initial revision
[moira.git] / clients / moira / Doc / internal.mss
1 @Comment($Header$)
2 @Make(Manual)
3 @Device(PostScript)
4 @PageFooting(center "Draft of @value(date)")
5 @style(spacing = 1.5, indent 5, FontFamily = TimesRoman, size = 12)
6 @style(LeftMargin 1 inch, RightMargin 1 inch)
7
8 @Begin(TitlePage)
9 @Begin(TitleBox)
10 @b[The Athena Service Management System]
11 @blankspace ( 1 line )
12 @b[SMS Client Internals Document]
13 @blankspace ( 1 line )
14 @i[Chris D. Peterson]
15 @End(TitleBox)
16 @CopyrightNotice(Massachusetts Institute of Technology)
17 @End(TitlePage)
18
19 @Chapter(Introduction)
20
21 The @i(Sms Client) program was designed to allow ordinary users a
22 simple method of performing all database manipulations common here at
23 @i(Project Athena).  The user interacts with the program through a
24 terminal based menu.  This allows use of sms on a wide variety of
25 platforms.  Unlike previous packages where many different clients were
26 necessary to perform all these tasks, the @i(Sms Client) program
27 allows all operations to be performed from one application.  This
28 saves the user time and effort by having all common operations in one
29 convenient place.  I have spent a good deal of time cleaning up the
30 code to make it uniform throughout the entire client and am writing
31 this document to explain some of the decisions. My hope is that this
32 will allow you to add features with a minimum of amount effort, as
33 well as easing the transition between your code and mine.
34
35 @Chapter(Overview)
36
37 This section presents general concepts that hold throughout the code.
38 Some of the items may seem trivial, but together they keep the code
39 consistent and understandable.
40
41 @Section(File Organization)
42
43 Most files correspond to one type of item in the @i(SMS) database,
44 such as lists, machines, clusters, etc.  These files are self
45 contained so that you can pick and choose which of these you would
46 like to use in any new client you decide to build. There are a few
47 special files that do not follow this convention.
48 @begin(description)
49
50 @i[util.c]@\Utility functions used by many of the other files.
51
52 @i[menu.c]@\Menu definitions for the entire application.
53
54 @i[main.c]@\The main driver that handles application start up.
55
56 @i[delete.c]@\Functions that handle deletion of lists and users.
57
58 @i[globals.c]@\All global variable definitions.
59 @end(description)
60
61 @Section(Command Organization)
62
63 Each menu item has one and only one function associated with it,
64 although the same function may be used by two identical menu items.
65 The arguments passed to these functions from the menu package are an
66 array of character strings and the number of strings in the array.
67 The first argument in the array (argv[0]) is the name of the menu item
68 that has been selected.  Thus the actual user specified arguments are
69 passed starting at the second argument (argv[1]).
70
71 @Section(Naming and Comment Conventions)
72
73 @Index(Variables)
74 @Index(Functions)
75
76 I use all capital letters for constants, while variables are all small
77 letters, and functions are represented by mixing capital and small
78 letters, capitalizing each word in the function name.  I use long
79 function names as functions are usually not called often, and long
80 names are much more descriptive.  There are a few functions that do
81 not follow the mixed caps and small convention, these are generally
82 those I called out of @i(SMSLib), @i[CLib], or the menu package.
83
84 @Index(Comments)
85
86 Each file has a header containing the Revision Control System (RCS)
87 modification time and some history information, as well as some
88 information about the file.  The template for this is a file named
89 'header'.  Each function has a comment preceding it describing the
90 function, all variables used, and the value that this function
91 returns.  Notes of special concern for this function are also listed
92 here.  The function template is in a file called, surprisingly enough,
93 'function'.  Other comments are placed where appropriate.
94
95 @Section(Retrieving data from the server)
96 @Label(queue-def)
97
98 Since one of the limitations of @i[SMS] is that no query may be
99 executed recursively, all information returned by a query must be
100 received before another query can be executed.  To facilitate
101 programming simplicity I store the information returned from each
102 query into a queue as soon as it is received.  This allows a simple,
103 although rather memory intensive, method of getting around this
104 problem.  Another advantage of this method is that since no operations
105 are taking place on the data as it comes back from the server the time
106 that the server spends sending the data to the clients is kept to a
107 minimum, a necessity in large-scale environments.
108
109 @Chapter[Application Wide Definitions]
110
111 This section will cover all items that cross function boundaries,
112 including global variables, structure definitions, and constant
113 definitions.
114
115 @Section[Global Variables]
116
117 @Label(Globals)The @i[SMS Client] has a few global variables.  Since
118 you will run into them throughout the application they warrant mention
119 here.
120 @Index(program_name)
121 @Index(user)
122 @Index(verbose)
123 @Index(found_some)
124 @begin(description)
125 @i[program_name] @\This is the name of the program currently being
126 executed, and is retrieved from argv[0] in @i[main.c].
127
128 @i[user] @\This is the name of the user currently executing the program,
129 and is also set in @i[main.c].
130
131 @i[verbose] @\This is a boolean value that, when FALSE turns off the
132 delete confirmation.  For more information see section @ref(confirm).
133
134 @i[found_some] @\This is a boolean that allows the @b[PrintByType()]
135 (sect. @ref(pbytype) function to be able to communicate with the
136 function calling the query that invokes it, as well as among calls to
137 itself.
138 @end(description)
139
140 @Section[Structure Definitions]
141
142 @Index(qelem)
143
144 The only global structure definition is the one for the queue element.
145 What I will refer to as the queue is actually a doubly linked list
146 that all my queue manipulation functions (sect. @ref(queuecount))
147 treat as a true queue.
148
149 @begin(Format)
150 struct qelem {
151   struct    qelem *q_forw;
152   struct    qelem *q_back;
153   char * q_data;
154 };
155 @end(Format)
156
157 The queue data need not be a string; @i[char *] is used as a generic
158 pointer here.
159
160 @Section[Definitions]
161
162 @Index(FVoid)
163 @Index(FInt)
164 @Index(FCharStar)
165
166 For readability there are a few important global definitions.
167 Function pointers in @i[C] tend to be tough to read so I have typedef'ed the
168 function pointers; FVoid, FInt, and FCharStar.  These refer to functions
169 that return nothing, integers, and strings, respectively.
170
171 @Index(MOD_FORMAT)
172
173 Another global definition, MOD_FORMAT, is used to format the
174 modification information of an item for printing.  It is important that
175 all modification information is presented to the user with this
176 format, to keep the @i[SMS Client] consistent.
177
178 @Index(Infodefs)
179 @Label(infodefs)
180
181 Information about an item in the database is returned by sms_query()
182 in an array of strings.  Remembering what @i[info][7] is can be
183 difficult and it is possible that in future updates of the @i[SMS
184 Server] @i[info][7] may contain completely different information.  To
185 solve both of these problems I have created a set of definitions for
186 each element of the argument list of each data type that the @i[SMS
187 Client] uses.  A list of these can be found in appendix
188 @ref(a_infodefs), as well as the file @i[infodefs.h].
189
190 @Chapter(Utility Functions)
191
192 I created several utility functions that handle common operations used
193 by many of the functions in the @i[SMS Client].  These functions
194 perform things like the storing of information in a queue as it comes
195 in from the @i(SMS Server), queue manipulation, querying the user, 
196 and printing information.
197
198 @Section(Storing and Freeing the Queue) 
199
200 As noted in section @ref(queue-def), all incoming information from the
201 @i(SMS Server) is stored in a queue as soon as it is received.  The
202 function that does this, @b[StoreInfo()], as well the one that frees the
203 queue when we are finished with it, @b[FreeQueue()], are described here.
204
205 @Index(StoreInfo) 
206
207 Use the function @b[StoreInfo()] to store all information received
208 from the @i[SMS Server] into a queue.  Space for this queue is
209 dynamically allocated using malloc().  The actual information is
210 stored in a NULL terminated array of strings.  The number of strings
211 in this array can be easily found with the function @b[CountArgs()]
212 (sect. @ref(countargs)).
213 @begin(format)
214
215 int
216 StoreInfo(@i[argc, argv, data])
217 int @i[argc];
218 char ** @i[argv];
219 char * @i[data];
220 @end(format)
221 @begin(Description)
222
223 @i[argc] @\The number of strings passed in argv.
224
225 @i[argv] @\An array of strings to be stored in the queue.
226
227 @i[data] @\A pointer to the previous element in this queue, or NULL if@\it
228 should create a new queue.  This is updated with each call to @b[StoreInfo()]
229 and the value associated with this pointer is the last element in the
230 queue.
231
232 @end(Description)
233 @blankspace(1 line)
234 Here is an example of an @i[SMS] query that would use this function to store
235 its arguments.
236
237 @Begin[Format]
238
239 struct qelem * elem = NULL;
240 status = sms_query("query handle", num_args, args, StoreInfo, &elem);
241
242 @End[Format]
243
244 The variable elem must initially be set to NULL, or @b[StoreInfo()]
245 will try to add the first element of this queue to a currently
246 existing queue that is really just the garbage left on the stack.  The
247 value of elem when this query returns is the last element in the
248 queue, and the function @b[QueueTop()] (section @ref(queuetop)) should
249 be used to get the top element of the queue, which is expected by most
250 other queue operations.
251
252 @Center(________)
253
254 @Index(FreeQueue)
255
256 To free the queue and any data associated with it, the function
257 @b[FreeQueue()] is used.  This function expects a queue similar to the
258 one created by the @b[StoreInfo()] function.  @b[FreeQueue()] frees
259 all memory associated with this particular queue, and will do bad
260 things if the information stored in the queue is not a NULL
261 terminated, allocated array of allocated strings.  All allocations
262 are assumed to have been done with the @i[C] malloc() function.
263
264 @begin(Format)
265
266 void
267 FreeQueue(@i[elem])
268 struct qelem * @i[elem];
269 @end(Format)
270 @begin(Description)
271
272 @i[elem] @\Any element in the queue.  The entire queue will be freed
273 regardless of the element passed.
274 @end(Description)
275
276 @Section[Queue Manipulation]
277
278 The following group of functions perform common tasks that involve
279 retrieving information from or manipulating a queue.  All these functions
280 will handle NULL passed to them in an appropriate manner, either returning
281 zero, or NULL.
282
283 @Label(queuetop)
284 @Index(QueueTop)
285
286 To find the top element of a queue use the function @b[QueueTop()].  
287
288 @begin(Format)
289
290 struct qelem * 
291 QueueTop(@i[elem])
292 struct qelem * @i[elem];
293 @end(Format)
294 @begin(Description)
295 @i[elem] @\Any element in the queue.
296 @end(Description)
297
298 @blankspace(1 line)
299
300 @b[QueueTop()] returns the top element of the queue defined by its
301 argument.
302
303 @Center(________)
304
305
306 @label(queuecount)
307 @Index(QueueCount)
308
309 The function @b[QueueCount()] counts the number of elements in a queue.
310
311 @begin(Format)
312 int
313 QueueCount(@i[elem])
314 struct qelem * @i[elem];
315 @end(Format)
316 @begin(Description)
317 @i[elem] @\Any element in the queue.
318 @end(Description)
319
320 @blankspace(1 line)
321
322 @b[QueueCount()] returns the number of elements in the queue defined
323 by it argument, it need not be the top element, any
324 element will do.
325
326 @Section[Array Manipulation]
327
328 The arrays of strings have some manipulation functions of their own.
329 All arrays used in the @i[SMS Client] are assumed to be NULL terminated. 
330 In general this is no problem as @b[StoreInfo()] creates NULL terminated
331 arrays.
332
333 @Label(countargs)
334 @Index(CountArgs)
335
336 @b[CountArgs()] counts the number of elements in a NULL
337 terminated array of strings.
338
339 @begin(Format)
340 int
341 CountArgs(@i[info])
342 char ** @i[info];
343 @end(Format)
344 @begin(description)
345 info @\A NULL terminated array of character strings.
346 @end(description)
347
348 @blankspace(1 line)
349
350 @b[CountArgs()] returns the number of strings in the NULL terminated array
351 of strings passed to it.  A common use of @b[CountArgs()] is to tell
352 sms_query() how many items are in the argument list passed to the
353 query, as shown below.
354 @begin(format)
355
356 status = sms_query("query", CountArgs(args), args, StoreInfo, &elem);
357 @end(format)
358
359 @Center(________)
360 @Index(FreeInfo)
361
362 To free all elements in a NULL terminated array of strings use the 
363 @b[FreeInfo()] function.
364
365 @begin(Format)
366 void
367 FreeInfo(@i[info])
368 char ** @i[info];
369 @end(Format)
370
371 @begin(Description) 
372
373 @i[info] @\A NULL terminated array of strings allocated with malloc(),
374 to be freed.
375 @end(Description)
376
377 @Center(________)
378
379
380 @Label(sinn)
381 @Index(SlipInNewName)
382
383 Most update queries use the same argument list that is returned by the
384 information query for the database item is question.  For instance,
385 update_list uses almost the same arguments that get_list_info returns.
386 The difference in these arguments lists is that update queries expect
387 the new name to be the second element in the list.  The
388 @b[SlipInNewName()] function adds the new name as the second argument
389 in the list passed to it, bumping all the other arguments down one
390 slot.
391
392 @begin(Format)
393 void
394 SlipInNewName(@i[info, name])
395 char ** @i[info];
396 char * @i[name];
397 @end(Format)
398
399 @begin(Description)
400 @i[info] @\A NULL terminated array of strings.
401
402 @i[name] @\The new name to be slipped into @i[info] at position @i[info][1].
403 @end(Description)
404
405 @Blankspace(1 line)
406
407 Once @b[SlipInNewName()] has been performed on a argument list do not
408 try to use the definitions for that type of element,  as they will be
409 wrong.  Don't use @i[info][L_ACE] to try to retrieve the ace of the
410 list, as this function has shifted all the items except the old name
411 down one element.
412
413 @Section[Special Queue Functions]
414
415 The following two functions @b[Loop()] and @b[QueryLoop()] are used
416 when an operation needs to be performed on every element of the queue.
417 The difference between these two functions is that @b[QueryLoop()]
418 presents a method of asking the user if the operation should be
419 performed, while @b[Loop()] just performs it on each element.
420
421 @Index(Loop)
422 @Index(LoopFunc)
423
424 To perform an operation on every element in the queue use the
425 @b[Loop()] function.
426
427 @begin(Format)
428 void
429 Loop(@i[top, LoopFunc])
430 struct qelem * @i[top];
431 FVoid @i[LoopFunc];
432 @end(Format)
433 @begin(Description)
434 @i[top] @\The top element of the queue.
435
436 @i[LoopFunc] @\The function to perform on each element of the queue.
437 @end(Description)
438
439 @blankspace(1 line)
440
441 The @i[LoopFunc] has the following format and is performed with the
442 data of each element in the queue.
443
444 @begin(Format)
445 void
446 LoopFunc(@i[info])
447 char ** @i[info];
448 @end(Format)
449 @begin(Description)
450 @i[info] @\The array of strings that is stored as the @i[q_data] of each element
451 of the queue.
452 @end(Description)
453
454 @blankspace(1 line)
455
456 No provision is made for the @i[LoopFunc] function to return a value.
457
458 @Center(________)
459
460
461 @Label(qloop)
462 @Index(QueryLoop)
463 @Index(PrintFunc)
464 @Index(QueryLoopFunc)
465
466 If you want to query the user before your function is called on each
467 element of the queue, use the @b[QueryLoop()] routine.
468
469 @Begin[Format]
470 void
471 QueryLoop(@i[top, PrintFunc, QueryLoopFunc, query_string])
472 struct qelem * @i[top];
473 FCharStar @i[PrintFunc];
474 FVoid @i[QueryLoopFunc];
475 char * @i[query_string];
476 @End[Format]
477 @begin(Description)
478 @i[top] @\The top element of the queue.
479
480 @i[PrintFunc] @\The function that will print information to the user
481 about each specific element of the queue, its return value is appended
482 to the query string, and asked as a @b[YesNoQuitQuestion()] (sect.
483 @ref[ynqquestion]) of the user.
484
485 @i[QueryLoopFunc] @\This function is called  if the user answers yes to the
486 question asked of him, or if there is only one element in the queue.
487
488 query_string @\Basic prompt for the @b[YesNoQuitQuestion()] asked of
489 the user, the string returned by the @i[PrintFunc] is appended to this
490 string to form the full prompt.
491 @end(Description)
492
493 @blankspace(1 line)
494
495 @Index(PrintFunc)
496
497 @i[PrintFunc] is called using the data stored in each element of the
498 queue, unless there is only one element in the queue, in which case
499 @i[QueryLoopFunc] is called without querying the user. @i[PrintFunc]
500 has the following format.
501
502 @begin(Format)
503 char *
504 PrintFunc(@i[info])
505 char ** @i[info];
506 @end(Format)
507 @begin(Description)
508
509 @i[info] @\The array of strings that is stored as the @i[q_data] of
510 each element in the queue.
511 @end(Description)
512
513 @blankspace(1 line)
514
515 The @i[PrintFunc] returns a string that is to be appended to the
516 query_string() of the @b[QueryLoop()] function.  This string is then
517 used to ask the user if the @i[QueryLoopFunc] should be called.  The
518 return string from the @i[PrintFunc] is usually just the name of the
519 item contained in the data field of each queue element.
520
521 @Index(QueryLoopFunc)
522
523 @i[QueryLoopFunc] is called each time the user answers 'yes' to the
524 question asked of him, with the current element's information.  The
525 only exception to this is if the queue has only one element, in which
526 case @i[QueryLoopFunc] is called immediately with @i[one_item] set to TRUE.
527 @i[QueryLoopFunc] has this format.
528
529 @begin(Format)
530 void
531 QueryLoopFunc(@i[info, one_item])
532 char ** @i[info];
533 Bool @i[one_item]
534 @end(Format)
535 @begin(Description) 
536
537 @i[info] @\The array of strings that is stored as the @i[q_data] of
538 each element in the queue.
539
540 @i[one_item] @\This is TRUE if this function is being called without asking
541 the user, because there is only one item in the queue.
542 @end(Description)
543
544 @blankspace(1 line)
545
546 No provision is made for the @b[QueryLoop()] function to return a value.
547
548 @b[QueryLoop()] automatically performs the @i[QueryLoopFunc] without
549 calling the @i[PrintFunc] if there is only one item in the queue, but
550 the @i[QueryLoopFunc] is alerted to this fact by the @i[one_item]
551 variable.  If there is more than one item on the queue the the
552 @i[PrintFunc] is executed, and the user is prompted, as in the
553 following example.
554
555 @begin(format)
556 @tabset(10)
557
558 @b[Source Code:]
559
560 QueryLoop(top_of_queue, PrintListInfo, UpdateList, "Would you like to update list");
561
562 @tabclear()
563 @tabset(50, 60)
564 @b[User Sees:]
565
566 List: foo  @\Members: @\35
567 This list is a group@\GID: @\9803
568
569 Would you like to update list foo (y/n/q) [n]: 
570 @end(format)
571
572 This question is asked of the user for every item in the queue, and if
573 the answer is yes then the @i[QueryLoopFunc] is called.  If the answer
574 is no then it continues onto the next element, quit drops out of the
575 loop entirely.
576
577 @Index(NullPrint)
578
579 The return value of the @i[PrintFunc] is the name of the list in the
580 above example (i.e. foo).  A simple print function, @b[Nullprint()],
581 is detailed in section @ref(nullprint). If @b[Nullprint()] were used
582 in the above example following would be the result:
583
584 @blankspace(1 line)
585
586 @begin(Format)
587 Would you like to update list foo (y/n/q) [n]: 
588 @end(Format)
589
590 @Section[Generic @i{SMS} query routines]
591
592 These two very common routines are used as sms_query() callbacks.
593 Using these common routines helps other programmers immediately
594 identify what type of tuples your query is expected to return.
595
596 @Index(Scream)
597
598 Use the @b[Scream()] function when you do not expect any tuples to be
599 returned by the @i[SMS Server], as in an update, add, or delete query.
600
601 @begin(Format)
602 int
603 Scream()
604 @end(Format)
605
606 A Sample use of this function.
607
608 @begin(Format)
609 status = sms_query("update_list", CountArgs(args), args, Scream, NULL);
610 @end(Format)
611
612 @Center(________)
613
614
615 @Index(NullFunc)
616
617 @b[NullFunc()] does nothing at all with the tuples, it just ignores them.
618
619 @begin(Format)
620 int
621 NullFunc()
622 @end(Format)
623
624 @b[NullFunc()] is useful when you are expecting tuples to be returned,
625 but are not interested in their contents, I used it when I was testing
626 for existence of a list by performing a count_members_of_list query
627 and then testing the return value, but was not interested in the
628 tuples. A sample use of this @b[NullFunc()].
629
630 @begin(Format)
631 status = sms_query("get_list_info", CountArgs(args), args, NullFunc, NULL);
632 @end(Format)
633
634 @Section[Retrieving User Input]
635
636 To keep a consistent user interface across the entire application, the
637 @i[SMS Client] uses the following functions to handle most user input.
638 The only other accepted method of retrieving user input is by making
639 a call to @b[Prompt_input()], which is in the menu library, and the
640 basis for all these functions.
641
642 @Index(PromptWithDefault)
643
644 Use @b[PromptWithDefault()] when you need to prompt the user for a value
645 and you want to provide him with a default value.
646
647 @begin(Format)
648 int
649 PromptWithDefault(@i[prompt, buf, buflen, def])
650 char * @i[prompt], * @i[buf];
651 int @i[buflen];
652 char * @i[def];
653 @end(Format)
654
655 @begin(Description)
656 prompt @\The string to prompt the user with.
657
658 buf @\The buffer to return the answer in.
659
660 buflen @\The length of the return buffer.
661
662 def @\The default return value (if NULL then "" is the default).
663
664 @End[Description]
665
666 @Blankspace( 1 line)
667
668 A typical call to this function is as follows:
669 @begin(format)
670
671 @b[Source Code:]
672
673 PromptWithDefault("Input a value for the string", buf, BUFSIZ, "foo");
674
675 @b[User Sees:]
676
677 Input a value for the string [foo]: 
678
679 @end(format)
680
681 @b[PromptWithDefault()] will return (-1) if the user breaks out of this
682 prompt with control-C or some other break character.
683
684 @Center(________)
685
686
687 @Label(ynquestion)
688 @Index(YesNoQuestion)
689
690 @b[YesNoQuestion()] is used to ask the user a question that is best
691 answered with a response of either yes or no.  It also gives the user
692 a default value in the same form as @b[PromptWithDefault()]. 
693
694 @begin(Format)
695 Bool
696 YesNoQuestion(@i[prompt, bool_def])
697 char @i[*prompt];
698 Bool @i[bool_def];
699 @end(Format)
700
701 @begin(Description)
702 @i[prompt] @\The string to prompt the user with.
703
704 @i[bool_def] @\The default value, either TRUE or FALSE.
705 @end(Description)
706
707 @blankspace(1 line)
708
709 @b[YesNoQuestion()] returns either TRUE or FALSE, or possibly (-1) on
710 a break by the user.  The only accepted values from the user are 'y',
711 'Y', 'n', and 'N'.  All other values prompt the user with "Please
712 answer 'y' or 'n'." and ask the question again.
713
714 @Center(________)
715
716
717 @Label(ynqquestion)
718 @Index(YesNoQuitQuestion)
719
720 Use @b[YesNoQuitQuestion()] when you want the user to have the option to
721 quit as well as answer yes or no.
722
723 @begin(Format)
724 Bool
725 YesNoQuitQuestion(@i[prompt, bool_def])
726 char @i[*prompt];
727 Bool @i[bool_def];
728 @end(Format)
729
730 @begin(Description)
731
732 @i[prompt] @\The string to prompt the user with.
733
734 @i[bool_def] @\The default value, either TRUE or FALSE.
735 @end(Description)
736
737 @blankspace(1 line)
738
739 @b[YesNoQuitQuestion()] is very similar to @b[YesNoQuestion()], in
740 fact the only difference is that this function interprets the keys 'q'
741 and 'Q' the same as hitting a break, causing
742 @b[YesNoQuitQuestion()] to return (-1).
743
744 @Center(________)
745
746
747 @Label(confirm)
748 @Index(Confirm)
749
750 When you want to ask the user for delete confirmation use the @b[Confirm()]
751 function.
752
753 @begin(Format)
754 Bool
755 Confirm(@i[prompt])
756 char * @i[prompt];
757 @end(Format)
758 @begin(Description)
759 @i[prompt] @\The string to prompt the user with.
760 @end(Description)
761
762 @blankspace(1 line)
763
764 @b[Confirm()] is a specialized user input function.  This function is
765 meant to be used only when making delete confirmation.  It will
766 immediately return TRUE if the verbose global variable (see section
767 @ref(globals)) is FALSE, implying that no confirmation is wanted.
768 Otherwise it asks the user a @b[YesNoQuestion()] using its argument as
769 the prompt, with a default value of FALSE.  If the user answers yes
770 then the function will return TRUE, otherwise FALSE is returned.
771
772 @Center(________)
773
774
775 @Label(gvfu)
776 @Index(GetValueFromUser)
777
778 The @b[GetValueFromUser()] routine is used to update a string that was
779 previously allocated with malloc().
780
781 @begin(format)
782 int
783 GetValueFromUser(@i[prompt, pointer])
784 char * @i[prompt], ** pointer;
785 @end(format)
786 @begin(Description)
787 @i[prompt] @\The string to prompt the user with.
788
789 @i[pointer] @\A pointer to the malloced item that is to be updated, or a
790 pointer to NULL.
791 @end(Description)
792
793 @Blankspace( 1 line )
794
795 @b[GetValueFromUser()] returns SUB_ERROR if the user broke out of the
796 prompt with control-C, else SUB_NORMAL.  The old value is freed,
797 unless it is NULL, and the new value is allocated and pointed to by
798 @i[pointer].
799
800 @Center(________)
801
802
803 @Index(GetYesNoValueFromUser)
804
805 If the value to be updated is an @i[SMS] style boolean ("0" or "1")
806 then use the the @b[GetYesNoValueFromUser()] function, which asks the
807 user a @b[YesNoQuestion()].
808
809 @begin(Format)
810 int
811 GetYesNoValueFromUser(@i[prompt, pointer])
812 char * @i[prompt], ** @i[pointer];
813 @end(Format)
814
815 @begin(Description)
816 @i[prompt] @\The string to prompt the user with.
817
818 @i[pointer] @\A pointer to the malloced item that is to be updated, or a
819 pointer to NULL.
820 @end(Description)
821
822 @Blankspace( 1 line)
823
824 @b[GetYesNoValueFromUser()] also returns SUB_ERROR if the user broke
825 out of the prompt with control-C, and SUB_NORMAL otherwise.
826 @i[pointer] is freed - Unless it is NULL - and reset to point to a
827 properly allocated value of "0" or "1" depending upon the user's answer
828 to the question.
829
830 @Center(________)
831
832
833 @Index(GetFSTypes)
834
835 The @i[SMS Server] expects file types to be passed as an integer bit
836 mask.  Use the @b[GetFSTypes()] function to query the user about the
837 new value of this field.
838
839 @begin(Format)
840 int
841 GetFSTypes(@i[pointer])
842 char **  @i[pointer];
843 @end(Format)
844
845 @begin(Description) 
846 @i[pointer] @\A pointer to the current allocated filesystem type that
847 is to be updated, or a pointer to NULL.
848 @end(Description)
849
850 @Blankspace( 1 line)
851
852 @b[GetFSTypes()] returns SUB_ERROR if the user broke out of the prompt
853 with control-C, and SUB_NORMAL otherwise.  It also constructs the
854 correct bit field by asking the user about each type, providing a
855 default value, of course.  The new filesystem type is passed back as
856 the new value pointed to by @i[pointer].  If non-NULL the old pointer
857 is freed.
858
859 @Section[Printing Routines]
860
861 Here are a few general printing routines.  Most printing is done with
862 routines that are specific to the type of database item we are dealing
863 with, but these few printing functions are general enough to describe
864 here.
865
866 @Label(print)
867 @Index(Print)
868
869 Use the @b[Print()] function to print out all elements in each tuple 
870 returned by a call to sms_query().
871
872 @begin(Format)
873 int
874 Print(@i[argc, argv, callback]);
875 int @i[argc];
876 char ** @i[argv], * @i[callback];
877 @end(Format)
878
879 @begin(Description)
880 @i[argc] @\The number if strings passed in argv.
881
882 @i[argv] @\An array of strings that is the data to be stored in the queue.
883
884 @i[callback] @\Not Used.
885 @end(Description)
886
887 @blankspace(1 line)
888
889 @b[Print()] returns SMS_CONT.  Every time this function is called it
890 sets the global variable @i[found_some] to TRUE.
891
892 @Center(________)
893
894 @Label(pbytype)
895 @Index(PrintByType)
896
897 If you want something a bit more specialized then try
898 @b[PrintByType()].  If a string compare of @i[argv][0] and
899 @i[callback] shows them to be equal then the tuple is printed.  If
900 @i[callback] is NULL then it acts exactly like @b[Print()].
901
902 @begin(Format)
903 int
904 PrintByType(@i[argc, argv, callback]);
905 int @i[argc];
906 char ** @i[argv], * @i[callback];
907 @end(Format)
908
909 @begin(Description)
910 @i[argc] @\The number if strings passed in argv.
911
912 @i[argv] @\An array of strings that is the data to be stored in the queue.
913
914 @i[callback] @\@i[Argv][0] is compared to this with strcmp() and if
915 they are equal then the tuple printed.  In the special case where
916 callback is NULL all tuples are printed.
917 @end(Description)
918
919 @blankspace(1 line)
920
921 @b[PrintByType()] returns SMS_CONT.  Every time this function is
922 called it sets the global variable found_some to TRUE.
923
924 @Center(________)
925
926
927 @Index(PrintHelp)
928
929 If the help information is stored in a NULL terminated array of strings
930 then use the @b[PrintHelp()] function to print the information for the user.
931
932 @begin(Format)
933 int
934 PrintHelp(@i[message])
935 char ** @i[message];
936 @end(Format)
937
938 @begin(Description)
939 @i[message] @\The help message stored in a NULL terminated array of strings.
940 @end(Description)
941
942 @blankspace(1 line)
943
944 @b[PrintHelp()] returns DM_NORMAL to allow help routines to remain as
945 simple as possible.
946
947 @Center(________)
948
949
950 @Index(NullPrint)
951 @Label(nullprint)
952
953 When using the @b[QueryLoop()] function (sect. @ref(qloop)) there are
954 times when all the @i[PrintFunc] needs to return is the name of the item, if
955 the item's name is the first element of the tuple then use the @b[NullPrint()]
956 function to retrieve this name.
957
958 @begin(Format)
959 char *
960 NullPrint(@i[info])
961 char ** @i[info];
962 @end(Format)
963 @begin(Description)
964 info@\ An array of strings.
965 @end(Description)
966
967 @blankspace(1 line)
968
969 @b[NullPrint()] returns the first element in the array passed to it,
970 @i[info][0].
971
972 @Section[Miscellaneous Utility Functions]
973
974 This section contains the rest of the utility functions, these don't
975 really fit into a category.
976
977 @Index(FreeAndClear)
978
979 Use @b[FreeAndClear()] to free a pointer and set it to NULL.
980
981 @Begin[Format]
982 void
983 FreeAndClear(@i[pointer, free_it])
984 char ** @i[pointer];
985 Bool @i[free_it];
986 @End[Format]
987
988 @begin(Description) 
989
990 @i[pointer] @\A pointer to the item to free or clear, if this item is
991 NULL then the function does not try to free it.
992
993 @i[free_it] @\This function always sets the item to NULL, but only if
994 this is TRUE is it freed.
995
996 @end(Description)
997
998 @Blankspace(1 line)
999 @Center(________)
1000
1001
1002 @Index(ValidName)
1003
1004 @b[ValidName()] check to see if string is a valid name for a new
1005 item in the database.
1006
1007 @begin(Format)
1008 Bool
1009 ValidName(@i[s])
1010 char * @i[s];
1011 @end(Format)
1012
1013 @begin(Description)
1014 @i[s] @\The string to check.
1015 @end(Description)
1016
1017 @Blankspace( 1 line )
1018
1019 If the name is not valid, @b[ValidName()] alerts the user to the
1020 problems encountered and returns FALSE.  Checks are made to see if
1021 this name contains a wildcard, contains spaces, or has no characters
1022 at all.  This is by no means an exhaustive search, but does handle some
1023 common things that confuse the database.
1024
1025 @Center(________)
1026
1027
1028 @Index(ToggelVerboseMode)
1029
1030 The @b[ToggleVerboseMode()] function is associated with the menu items
1031 that allows the user to toggle the verbose global variable (see sect.
1032 @ref(globals)).
1033
1034 @Center(________)
1035
1036
1037 @Index(Strsave)
1038
1039 Use the @b[Strsave()] function to allocate space for a new string.
1040
1041 @begin(Format)
1042 char *
1043 Strsave(@i[str])
1044 char * @i[str];
1045 @end(Format)
1046
1047 @begin(Description)
1048 @i[str] @\The string that needs to have space allocated for it.
1049 @end(Description)
1050
1051 @Blankspace( 1 line )
1052
1053 @b[Strsave()] returns an allocated copy of the string passed to it.
1054
1055 @Center(________)
1056
1057
1058 @Index(EncryptMITID)
1059 @Index(RemoveHyphens)
1060
1061 To save an MIT ID number two functions are needed, @b[EncryptMITID()] and
1062 @b[RemoveHyphens()].
1063
1064 @begin(Format)
1065 void
1066 EncryptMITID(@i[sbuf], @i[idnumber], @i[first], @i[last])
1067 char * @i[sbuf], * @i[idnumber], * @i[first], * @i[last];
1068 @end(Format)
1069
1070 @begin(Description)
1071 @i[spbuf] @\The buffer used to return the encrypted id number.
1072
1073 @i[idnumber] @\The unencrypted id number.
1074
1075 @i[first, last] @\The name of the user whose id number we are encrypting.
1076
1077 @end(Description)
1078
1079 @Blankspace(1 line)
1080 @Center(________)
1081
1082
1083 @begin(Format)
1084 void
1085 RemoveHyphens(@i[str)]
1086 char * @i[str];
1087 @end(Format)
1088
1089 @begin(Description) 
1090
1091 @i[str] @\This is the string with hyphens to remove, when the function
1092 returns it will no longer have hyphens.
1093 @end(Description)
1094
1095 @Chapter[Function Organization within Files]
1096
1097 The functions within each of the files tend to be quite similar.  I
1098 have organized these so that at the top of the file are all the
1099 general routines for the type of element currently being worked upon.
1100 In @i[attach.c], for example, there is a @b[PrintFSInfo()] function, an
1101 @b[AskFSInfo()] function, and a @b[GetFSInfo()] function.  Each of the
1102 item types will have a file that contains very similar functions, and
1103 all will be grouped near the top of the file.  As an example consider the
1104 general functions in @i[attach.c].
1105
1106 @b[PrintFSInfo()] is used to print out all the information about a filesystem.
1107
1108 @begin(Format)
1109 static char *
1110 PrintFSInfo(@i[info])
1111 char ** @i[info];
1112 @end(Format)
1113
1114 @begin(Description)
1115 @i[info] @\A NULL terminated array of strings that contains all information 
1116 about a filesystem.
1117 @end(Description)
1118
1119 @blankspace(1 line)
1120
1121 @b[PrintFSInfo()] has the same format as @i[PrintFunc] (sect.
1122 @ref(qloop)) and can be used as the @i[PrintFunc] for @b[QueryLoop()]
1123 calls in the functions that update and delete filesystems.
1124
1125 @Center(________)
1126
1127
1128 @b[AskFSInfo()] is used to ask the user to update the current filesystem
1129 information.
1130
1131 @begin(Format)
1132 static char **
1133 AskFSInfo(@i[info, name])
1134 char ** @i[info];
1135 Bool @i[name];
1136 @end(Format)
1137
1138 @begin(Description) 
1139
1140 @i[info] @\A NULL terminated array of malloced strings that contains
1141 all information about a filesystem.  When the function is called this
1142 array contains the default values to present to the user, and when the
1143 function is returned this array contains the argument list for the
1144 update or add query.
1145
1146 @i[name] @\A boolean value that when TRUE tells this function to ask
1147 the user for a new value for the name of this filesystem, and then
1148 slip it into the @i[info] list, using @b[SlipInNewName()] (sect.
1149 @ref(sinn))
1150 @end(Description)
1151
1152 @Blankspace( 1 line )
1153
1154 The return value of @b[AskFSInfo()] is just the @i[info] array after
1155 it has been updated with the new values.  This function is used to
1156 perform most of the information gathering in the update and add
1157 filesystem queries.  For an update query the information returned from
1158 a @i[get_filesys_by_label] can be used for the @i[info] array, but for
1159 an add filesystem, the program must come up with a reasonable set
1160 default values for the @i[info] array.
1161
1162 If the @i[name] flag is set then the @b[SlipInNewName()] function is
1163 called to add a new name to the @i[info] array, this causes the array
1164 indices for most values to be changed and thus the predefined values
1165 used to access the information in this array can no longer be used
1166 (see sections @ref(infodefs) and @Ref(sinn)).
1167
1168 @Center(________)
1169
1170
1171 The @b[GetFSInfo()] function is used to to perform common information
1172 gathering @i[SMS] queries for a filesystem.
1173
1174 @begin(Format)
1175 static struct qelem *
1176 GetFSInfo(@i[type, name])
1177 int @i[type];
1178 char * @i[name];
1179 @end(Format)
1180
1181 @begin(Description)
1182 @i[type] @\The type of filesystem query to make, can be one of;
1183 LABEL, MACHINE, GROUP or ALIAS.  The valid names for @i[type] are 
1184 typedef'ed at the beginning of each file.
1185
1186 @i[name] @\The name to pass as the argument to the query.
1187 @end(Description)
1188
1189 @Blankspace(1 line)
1190
1191 The @b[GetFSInfo()] function is a simple method of making the most
1192 common information gathering @i[SMS] queries, it handles all return
1193 values from the call to sms_query() and returns the top element of a
1194 queue containing all information returned by the server.  If an error
1195 is detected then NULL is returned and an error message is printed to
1196 the user.
1197
1198 After this group of general functions come those that actually
1199 correspond to items in the menu.  These commonly perform get, add,
1200 update, and delete operations.  For more information on the functions
1201 in each of the files see the appendix @ref(fqlist).
1202
1203 @Appendix(The @i[SMS] Query String Array Definitions)
1204
1205 @Label(a_infodefs)
1206
1207 @Begin[Format]
1208
1209 /*
1210  *     This file contains all definitions that allow easy access to 
1211  * elements returned by most of the @i[SMS] queries.
1212  *
1213  *     If the order of the arguments in the @i[SMS] queries change (again)
1214  *  then all that needs to be changed are the values of these items 
1215  * and all should be well, (hopefully :-).
1216  *
1217  *                                 Chris D. Peterson - kit@@athena
1218  *                                   6/8/88
1219  */
1220
1221 @Begin[Verbatim]
1222
1223 #ifndef _infodefs_
1224 #define _infodefs_
1225
1226 #include "mit-copyright.h"
1227
1228 #define NAME 0
1229
1230 /* get_ace_use */
1231
1232 #define ACE_TYPE 0
1233 #define ACE_NAME 1
1234 #define ACE_END  2
1235
1236 /* alias queries. */
1237
1238 #define ALIAS_NAME  0
1239 #define ALIAS_TYPE  1
1240 #define ALIAS_TRANS 2
1241 #define ALIAS_END   3
1242
1243 /* Cluster information queries */
1244
1245 #define C_NAME       0
1246 #define C_DESCRIPT   1
1247 #define C_LOCATION   2
1248 #define C_MODTIME    3
1249 #define C_MODBY      4
1250 #define C_MODWITH    5
1251 #define C_END        6
1252
1253 /* Cluster Data information queries */
1254
1255 #define CD_NAME      0
1256 #define CD_LABEL     1
1257 #define CD_DATA      2
1258 #define CD_END       3
1259
1260 /* Delete Member from list queries. */
1261
1262 #define DM_LIST      0
1263 #define DM_TYPE      1
1264 #define DM_MEMBER    2
1265 #define DM_END       3
1266
1267 /* Filesys queries */
1268
1269 #define FS_NAME         0
1270 #define FS_TYPE         1
1271 #define FS_MACHINE      2
1272 #define FS_PACK         3
1273 #define FS_M_POINT      4
1274 #define FS_ACCESS       5
1275 #define FS_COMMENTS     6
1276 #define FS_OWNER        7
1277 #define FS_OWNERS       8
1278 #define FS_CREATE       9
1279 #define FS_L_TYPE       10
1280 #define FS_MODTIME      11
1281 #define FS_MODBY        12
1282 #define FS_MODWITH      13
1283 #define FS_END          14
1284
1285 /* Get List Of Member queries. */
1286
1287 #define GLOM_NAME     0
1288 #define GLOM_ACTIVE   1
1289 #define GLOM_PUBLIC   2
1290 #define GLOM_HIDDEN   3
1291 #define GLOM_MAILLIST 4
1292 #define GLOM_GROUP    5
1293 #define GLOM_END      6
1294
1295 /* General List information queries. */
1296
1297 #define L_NAME     0
1298 #define L_ACTIVE   1
1299 #define L_PUBLIC   2
1300 #define L_HIDDEN   3
1301 #define L_MAILLIST 4
1302 #define L_GROUP    5
1303 #define L_GID      6
1304 #define L_ACE_TYPE 7
1305 #define L_ACE_NAME 8
1306 #define L_DESC     9
1307 #define L_MODTIME  10
1308 #define L_MODBY    11
1309 #define L_MODWITH  12
1310 #define L_END      13
1311
1312 /* List Member information queries. */
1313
1314 #define LM_LIST   0
1315 #define LM_TYPE   1
1316 #define LM_MEMBER 2
1317 #define LM_END    3
1318
1319 /* Machine information queries */
1320
1321 #define M_NAME       0
1322 #define M_TYPE       1
1323 #define M_MODTIME    2
1324 #define M_MODBY      3
1325 #define M_MODWITH    4
1326 #define M_END        5
1327
1328 /*  Machine to cluster Mapping */
1329
1330 #define MAP_MACHINE  0
1331 #define MAP_CLUSTER  1
1332 #define MAP_END      2
1333
1334 /*  NFS phys. queries. */
1335
1336 #define NFS_NAME    0
1337 #define NFS_DIR     1
1338 #define NFS_DEVICE  2
1339 #define NFS_STATUS  3
1340 #define NFS_ALLOC   4
1341 #define NFS_SIZE    5
1342 #define NFS_MODTIME 6
1343 #define NFS_MODBY   7
1344 #define NFS_MODWITH 8
1345 #define NFS_END     9
1346
1347 /* PO box information queries */
1348
1349 #define PO_NAME    0
1350 #define PO_TYPE    1
1351 #define PO_BOX     2
1352 #define PO_END     3
1353
1354 /* Quota queries */
1355
1356 #define Q_FILESYS   0
1357 #define Q_LOGIN     1
1358 #define Q_QUOTA     2
1359 #define Q_DIRECTORY 3  
1360 #define Q_MACHINE   4
1361 #define Q_MODTIME   5
1362 #define Q_MODBY     6
1363 #define Q_MODWITH   7
1364 #define Q_END       8
1365
1366 /* User information queries */
1367
1368 #define U_NAME    0
1369 #define U_UID     1
1370 #define U_SHELL   2
1371 #define U_LAST    3
1372 #define U_FIRST   4
1373 #define U_MIDDLE  5
1374 #define U_STATE   6  
1375 #define U_MITID   7
1376 #define U_CLASS   8
1377 #define U_MODTIME 9
1378 #define U_MODBY   10
1379 #define U_MODWITH 11
1380 #define U_END     12
1381
1382 #endif _infodefs_      /* Do not add anything after this line. */
1383
1384 @End[Verbatim]
1385
1386 @End[Format]
1387
1388 @Appendix(List of Menus, Functions, and Query Names)
1389
1390 @Label(fqlist)
1391
1392 @blankspace(2 lines)
1393
1394 The menu tree for the @i[SMS Client] has three levels, the root, tier
1395 1 and tier 2.  A diagram of the menu tree is show in appendix @ref(tree).
1396 The root of the tree is composed of calls to other menus.
1397
1398 @blankspace(2 lines)
1399
1400 @begin(Group)
1401 @Center(Sms Database Manipulation)
1402 @begin(Verbatim)
1403
1404  1. (cluster)      Cluster Menu.
1405  2. (filesys)      Filesystem Menu.
1406  3. (list)         Lists and Group Menu.
1407  4. (machine)      Machine Menu.
1408  5. (nfs)          Physical NFS Menu.
1409  6. (user)         User Menu. 
1410  t. (toggle)       Toggle logging on and off.
1411  q. (quit)         Quit.
1412
1413 @end(Verbatim)
1414 @Hinge()
1415 @Section[First Tier Menus]
1416
1417 @Center{ @b[Cluster Menu] }
1418
1419 @begin(Verbatim)
1420
1421  1. (show)         Get cluster information.
1422  2. (add)          Add a new cluster.
1423  3. (update)       Update cluster information.
1424  4. (delete)       Delete this cluster.
1425  5. (mappings)     Machine To Cluster Mappings Menu.
1426  6. (c_data)       Cluster Data Menu.
1427  7. (verbose)      Toggle Verbosity of Delete.
1428  r. (return)       Return to previous menu.
1429  t. (toggle)       Toggle logging on and off.
1430  q. (quit)         Quit.
1431
1432 @end(Verbatim)
1433
1434 @Begin(Format)
1435 @tabset(20,40,60)
1436 show@\get_cluster
1437 add@\get_cluster@\add_cluster
1438 update@\get_cluster@\update_cluster
1439 delete@\get_cluster@\delete_cluster
1440
1441 @End[Format]
1442 @Hinge()
1443 @Center{ @b[Filesystem Menu] }
1444
1445 @begin(Verbatim)
1446
1447  1. (get)          Get Filesystem Name Information.
1448  2. (add)          Add New Filesystem to Database.
1449  3. (change)       Update Filesystem Information.
1450  4. (delete)       Delete Filesystem.
1451  5. (check)        Check An Association.
1452  6. (alias)        Associate with a Filesystem.
1453  7. (unalias)      Dissociate from a Filesystem.
1454  8. (quotas)       Quota Menu.
1455  9. (verbose)      Toggle Verbosity of Delete.
1456 10. (help)         Help ...
1457  r. (return)       Return to previous menu.
1458  t. (toggle)       Toggle logging on and off.
1459  q. (quit)         Quit.
1460
1461 @end(Verbatim)
1462
1463 @begin(Format)
1464 @tabset(20,40,60)
1465 get@\get_filesys_by_label
1466 add@\get_filesys_by_label@\add_filesys
1467 change@\get_filesys_by_label@\update_filesys
1468 delete@\get_filesys_by_label@\delete_filesys
1469 check@\get_alias
1470 alias@\get_alias@\add_alias
1471 unalias@\get_alias@\delete_alias
1472
1473 @end(Format)
1474 @Hinge()
1475 @Center{ @b[List Menu] }
1476
1477 @begin(Verbatim)
1478
1479  1. (show)         Display information about a list.
1480  2. (add)          Create new List.
1481  3. (update)       Update characteristics of a list.
1482  4. (delete)       Delete a List.
1483  5. (query_remove) Interactively remove an item from all lists.
1484  6. (members)      Member Menu - Change/Show Members of a List.
1485  7. (list_info)    List Info Menu.
1486  8. (quotas)       Quota Menu.
1487  9. (verbose)      Toggle Verbosity of Delete.
1488 10. (help)         Print Help.
1489  r. (return)       Return to previous menu.
1490  t. (toggle)       Toggle logging on and off.
1491  q. (quit)         Quit.
1492
1493 @end(Verbatim)
1494
1495 @begin(Format)
1496 @tabset(20,40,60)
1497 show@\get_list_info
1498 add@\get_list_info@\add_list
1499 update@\get_list_info@\update_list
1500 delete@\get_list_info@\get_ace_use
1501 @\count_members_of_list@\get_lists_of_member
1502 @\get_members_of_list@\delete_list
1503 @\delete_member_from_list
1504 query_remove@\get_lists_of_member@\delete_member_from_list
1505
1506 @end(Format)
1507 @Hinge()
1508 @Center{ @b[Machine Menu] }
1509
1510 @begin(Verbatim)
1511
1512  1. (show)         Get machine information.
1513  2. (add)          Add a new machine.
1514  3. (update)       Update machine information.
1515  4. (delete)       Delete this machine.
1516  5. (mappings)     Machine To Cluster Mappings Menu.
1517  6. (verbose)      Toggle Verbosity of Delete.
1518  r. (return)       Return to previous menu.
1519  t. (toggle)       Toggle logging on and off.
1520  q. (quit)         Quit.
1521
1522 @end(Verbatim)
1523
1524 @begin(Format)
1525 @tabset(20,40, 60)
1526 show@\get_machine
1527 add@\get_machine@\add_machine
1528 update@\get_machine@\update_machine
1529 delete@\get_machine@\delete_machine
1530
1531 @end(Format)
1532
1533 Delete machine needs to make some other checks. For lack of time these
1534 have not been implemented.
1535 @begin(Itemize)
1536 @tabset(45)
1537 Is the machine a server@\get_server_host_info
1538
1539 Is the machine an NFS server@\get_nfsphys
1540
1541 Are there any ACE's that this machine references@\get_server_host_access
1542 @end(Itemize)
1543
1544 @Hinge()
1545
1546 @Center{ @b[NFS Physical Menu] }
1547
1548 @begin(Verbatim)
1549
1550  1. (show)         Show an NFS server.
1551  2. (add)          Add NFS server.
1552  3. (update)       Update NFS server.
1553  4. (delete)       Delete NFS server.
1554  5. (quotas)       Quota Menu.
1555  6. (verbose)      Toggle Verbosity of Delete.
1556  r. (return)       Return to previous menu.
1557  t. (toggle)       Toggle logging on and off.
1558  q. (quit)         Quit.
1559
1560 @end(Verbatim)
1561
1562 @begin(Format)
1563 @tabset(20,40, 60)
1564 show@\get_nfsphys
1565 add@\get_nfsphys@\add_nfsphys
1566 update@\get_nfsphys@\update_nfsphys
1567 delete@\get_nfsphys@\get_filesys_by_nfsphys
1568 @\delete_nfsphys
1569
1570 @end(Format)
1571 @Hinge()
1572 @Center{ @b[User Menu] }
1573
1574 @begin(Verbatim)
1575
1576  1. (login)        Show user information by login name.
1577  2. (name)         Show user information by name.
1578  3. (class)        Show names of users in a given class.
1579  4. (modify)       Change all user fields.
1580  5. (adduser)      Add a new user to the database.
1581  6. (register)     Register a user.
1582  7. (delete)       Delete user.
1583  8. (udelete)      Delete user by uid.
1584  9. (pobox)        Post Office Box Menu.
1585 10. (quota)        Quota Menu.
1586 11. (verbose)      Toggle Verbosity of Delete.
1587  r. (return)       Return to previous menu.
1588  t. (toggle)       Toggle logging on and off.
1589  q. (quit)         Quit.
1590
1591 @end(Verbatim)
1592
1593 @begin(Format)
1594 @tabset(20,40, 60)
1595 login@\get_user_by_login
1596 name@\get_user_by_name
1597 class@\get_user_by_class
1598 modify@\get_user_by_login@\update_user
1599 adduser@\add_user
1600 register@\get_user_by_name@\register_user
1601 @\Kerberos server is queried also.
1602 delete@\delete_user@\get_filesys_by_label
1603 @\delete_filesys@\get_members_of_list
1604 @\delete_list@\count_members_of_list
1605 @\get_lists_of_member@\delete_member_from_list
1606 @\get_list_info@\get_ace_use
1607 udelete@\get_user_by_uid@\(plus all of the above).
1608
1609 @end(Format)
1610 @Hinge()
1611 @Section[Second Tier Menus]
1612
1613 @Center{ @b[Cluster Data Menu] }
1614
1615 @begin(Verbatim)
1616
1617  1. (show)         Show Data on a given Cluster.
1618  2. (add)          Add Data to a given Cluster.
1619  3. (delete)       Remove Data to a given Cluster.
1620  4. (verbose)      Toggle Verbosity of Delete.
1621  r. (return)       Return to previous menu.
1622  t. (toggle)       Toggle logging on and off.
1623  q. (quit)         Quit.
1624
1625 @end(Verbatim)
1626
1627 @begin(Format)
1628 @tabset(20,40, 60)
1629 show@\get_cluster_data
1630 add@\add_cluster_data
1631 delete@\get_cluster_data@\delete_cluster_data
1632
1633 @end(Format)
1634 @Hinge()
1635 @Center{ @b[List Information Menu] }
1636
1637 @begin(Verbatim)
1638
1639  1. (member)       Show all lists to which a given member belongs.
1640  2. (admin)        Show all items which a given member can administer.
1641  3. (groups)       Show all lists which are groups.
1642  4. (public)       Show all public mailing lists.
1643  5. (maillists)    Show all mailing lists.
1644  r. (return)       Return to previous menu.
1645  t. (toggle)       Toggle logging on and off.
1646  q. (quit)         Quit.
1647
1648 @end(Verbatim)
1649
1650 @begin(Format)
1651 @tabset(20,40, 60)
1652 member@\get_lists_of_member
1653 admin@\get_ace_use
1654 groups@\qualified_get_lists
1655 public@\qualified_get_lists
1656 maillists@\qualified_get_lists
1657
1658 @end(Format)
1659 @Hinge()
1660 @Center{ @b[Mappings Menu] }
1661
1662 @begin(Verbatim)
1663
1664  1. (map)          Show Machine to cluster mapping.
1665  2. (addcluster)   Add machines to a clusters.
1666  3. (remcluster)   Remove machines from clusters.
1667  4. (verbose)      Toggle Verbosity of Delete.
1668  r. (return)       Return to previous menu.
1669  t. (toggle)       Toggle logging on and off.
1670  q. (quit)         Quit.
1671
1672 @end(Verbatim)
1673
1674 @begin(Format)
1675 @tabset(20,40, 60)
1676 map@\get_machine_to_cluster_map
1677 addcluster@\get_machine@\get_cluster
1678 @\add_machine_to_cluster
1679 remcluster@\get_machine_to_cluster_map
1680 @\delete_machine_from_cluster
1681
1682 @end(Format)
1683 @Hinge()
1684 @Center{ @b[Membership Menu] }
1685
1686 @begin(Verbatim)
1687
1688  1. (add)          Add a member to this list.
1689  2. (remove)       Remove a member from this list.
1690  3. (all)          Show the members of this list.
1691  4. (user)         Show the members of type USER.
1692  5. (list)         Show the members of type LIST.
1693  6. (string)       Show the members of type STRING.
1694  7. (verbose)      Toggle Verbosity of Delete.
1695  r. (return)       Return to previous menu.
1696  t. (toggle)       Toggle logging on and off.
1697  q. (quit)         Quit.
1698
1699 @end(Verbatim)
1700
1701 @begin(Format)
1702 @tabset(20,40, 60)
1703 add@\add_member_to_list
1704 remove@\delete_member_from_list
1705 all@\get_members_of_list
1706 user@\get_members_of_list
1707 list@\get_members_of_list
1708 string@\get_members_of_list
1709
1710 @end(Format)
1711 @Hinge()
1712 @Center{ @b[Post Office Box Menu] }
1713
1714 @begin(Verbatim)
1715
1716  1. (show)         Show a user's post office box.
1717  2. (set)          Set (Add or Change) a user's post office box.
1718  3. (remove)       Remove a user's post office box.
1719  4. (verbose)      Toggle Verbosity of Delete.
1720  r. (return)       Return to previous menu.
1721  t. (toggle)       Toggle logging on and off.
1722  q. (quit)         Quit.
1723
1724 @end(Verbatim)
1725
1726 @begin(Format)
1727 @tabset(20,40, 60)
1728 show@\get_pobox
1729 set@\get_pobox@\get_server_locations
1730 @\set_pobox_pop@\set_pobox
1731 remove@\delete_pobox
1732
1733 @end(Format)
1734 @Hinge()
1735 @Center{ @b[Quota Menu] }
1736
1737 @begin(Verbatim)
1738
1739  1. (shdef)        Show default user quota (in KB).
1740  2. (chdef)        Change default user quota.
1741  3. (shquota)      Show a user's disk quota on a filesystem.
1742  4. (addquota)     Add a new disk quota for user on a filesystem.
1743  5. (chquota)      Change a user's disk quota on a filesystem.
1744  6. (rmquota)      Remove a user's disk quota on a filesystem.
1745  7. (verbose)      Toggle Verbosity of Delete.
1746  r. (return)       Return to previous menu.
1747  t. (toggle)       Toggle logging on and off.
1748  q. (quit)         Quit.
1749
1750 @end(Verbatim)
1751
1752 @begin(Format)
1753 @tabset(20,40, 60)
1754 shdef@\get_value
1755 chdef@\update_value@\get_value
1756 shquota@\get_nfs_quota
1757 addquota@\add_nfs_quota
1758 chquota@\get_nfs_quota@\update_nfs_quota
1759 rmquota@\get_nfs_quota@\delete_nfs_quota
1760 @end(Format)
1761 @end(Group)
1762
1763 @Appendix(Menu Tree Diagram)
1764
1765 @Label(tree)
This page took 0.182528 seconds and 5 git commands to generate.