]> andersk Git - moira.git/blob - clients/mmoira/stubs.c
specify path to synctree
[moira.git] / clients / mmoira / stubs.c
1 /*
2 ** Stub functions
3 */
4
5 #ifdef POSIX
6 #include        <unistd.h>
7 #endif
8 #include        <ctype.h>
9 #include        <stdio.h>
10 #include        <string.h>
11 #include        <X11/StringDefs.h>
12 #include        <X11/Intrinsic.h>
13 #include        <X11/Core.h>
14 #include        <X11/cursorfont.h>
15 #include        <Xm/Text.h>
16 #include        <Xm/MessageB.h>
17 #include        "mmoira.h"
18 #include        <sys/types.h>
19 #include        <sys/file.h>
20 #include        <fcntl.h>
21
22 static char rcsid[] = "$Header$";
23
24 void    extra_help_callback();
25 extern EntryForm *MoiraForms[];
26 static DoMoiraSelect(), DoReference();
27
28 static Widget   logwidget = NULL;
29
30
31 /* No-op action to mask built-in actions */
32
33 void noopACT(w, event, p, n)
34 Widget w;
35 XEvent *event;
36 String *p;
37 Cardinal *n;
38 {
39 }
40
41
42 /* Action to do a moira retrieve on what was clicked at */
43
44 void moiraRetrieveACT(w, event, p, n)
45 Widget w;
46 XEvent *event;
47 String *p;
48 Cardinal *n;
49 {
50     XmTextPosition pos;
51     XButtonEvent *be;
52
53     be = (XButtonEvent *)event;
54
55     pos = XmTextXYToPos(w, be->x, be->y);
56     DoMoiraSelect(pos, w, 0);
57 }
58
59
60 /* Action to modify the moira object that was clicked on */
61
62 void moiraModifyACT(w, event, p, n)
63 Widget w;
64 XEvent *event;
65 String *p;
66 Cardinal *n;
67 {
68     XmTextPosition pos;
69     XButtonEvent *be;
70
71     be = (XButtonEvent *)event;
72
73     pos = XmTextXYToPos(w, be->x, be->y);
74     DoMoiraSelect(pos, w, 1);
75 }
76
77
78 static XtActionsRec myactions[] = {
79     { "moiraRetrieve", moiraRetrieveACT },
80     { "moiraModify", moiraModifyACT },
81     { "noop", noopACT },
82 };
83
84
85 /* Create the log window, and setup the translation table to taking
86  * mouse clicks in it.
87  */
88
89 Widget
90 SetupLogWidget(parent)
91 Widget  parent;
92 {
93         Arg             wargs[10];
94         int             n;
95         XtTranslations  trans;
96
97         if (logwidget)
98                 return (logwidget);
99         
100         n = 0;
101         XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT);     n++;
102         XtSetArg(wargs[n], XmNeditable, False);                 n++;
103
104         logwidget = XmCreateScrolledText(       parent,
105                                                 "logwidget", 
106                                                 wargs, n);
107         XtManageChild(logwidget);
108
109         XtAppAddActions(XtWidgetToApplicationContext(logwidget),
110                         myactions, XtNumber(myactions));
111         trans = XtParseTranslationTable(resources.log_trans);
112         XtOverrideTranslations(logwidget, trans);
113         return (logwidget);
114 }
115
116
117 /* This actually does all of the work for handling mouse clicks.  It
118  * finds the surrounding text and decides what to do with the click,
119  * the actually starts the moira query or pops up the form.
120  */
121
122 static DoMoiraSelect(pos, w, modify)
123 XmTextPosition pos;
124 Widget w;
125 int modify;    
126 {
127     char *log, *p, *p1, *p2;
128     char name[256], type[256], type2[256];
129
130     log = XmTextGetString(w);
131     for (p = &log[pos]; p > log; p--)
132       if (isspace(*p) || *p == ':') break;
133
134     /* p now points to the beginning of the word on which the mouse was
135      * clicked.  Begin gross hacking to find the name and type of object.
136      */
137     /* get name */
138     p1 = p + 1;
139     p2 = name;
140     while (*p1 && !isspace(*p1)) *p2++ = *p1++;
141     *p2 = 0;
142     /* backup two words before for type2 */
143     while (p >= log && isspace(*p) || *p == ':') p--;
144     while (p >= log && !isspace(*p)) p--;
145     while (p >= log && isspace(*p)) p--;
146     while (p >= log && !isspace(*p)) p--;
147     p++;
148     p2 = type2;
149     /* new get type2 */
150     if (p > log) {
151         while (!isspace(*p)) *p2++ = *p++;
152         *p2++ = *p++;
153         /* skip additional whitespace */
154         while (isspace(*p)) p++;
155     }
156     /* get type & rest of type2 */
157     p1 = type;
158     while (*p && *p != ':' && !isspace(*p)) *p2++ = *p1++ = *p++;
159     *p2 = *p1 = 0;
160     /* Done! */
161 #ifdef DEBUG
162     printf("name \"%s\", type \"%s\" type2 \"%s\"\n", name, type, type2);
163 #endif /* DEBUG */
164     if (!strcasecmp(type, "USER") ||
165         !strcmp(type, "name") ||
166         !strcmp(type2, "Modified by") ||
167         !strcmp(type2, "User Ownership") ||
168         !strcmp(type2, "Login name") ||
169         !strcmp(type, "login")) {
170         DoReference(name, "select_user", MM_MOD_USER, MM_SHOW_USER,
171                     "get_user_account_by_login", modify);
172     } else if (!strcasecmp(type, "LIST") ||
173                !strcmp(type2, "Group Ownership")) {
174         DoReference(name, "select_list", MM_MOD_LIST, MM_SHOW_LIST,
175                     "get_list_info", modify);
176     } else if (!strcasecmp(type, "MACHINE") ||
177                !strcmp(type, "host") ||
178                !strcasecmp(type, "Server") ||
179                !strcmp(type, "on") ||
180                !strcmp(type, "Box")) {
181         DoReference(name, "select_machine", MM_MOD_MACH, MM_SHOW_MACH,
182                     "get_machine", modify);
183     } else if (!strcasecmp(type, "CLUSTER")) {
184         DoReference(name, "select_cluster", MM_MOD_CLUSTER, MM_SHOW_CLUSTER,
185                     "get_cluster", modify);
186     } else if (!strcasecmp(type, "FILESYSTEM") ||
187                !strcmp(type, "FILESYS") ||
188                !strcmp(type2, "syslib Data")) {
189         DoReference(name, "select_filsys", MM_MOD_FILSYS, MM_SHOW_FILSYS,
190                     "get_filesys_by_label", modify);
191     } else if (!strcmp(type2, "Filesystem Group")) {
192         DoReference(name, "order_fsgroup", MM_MOV_FSGROUP, MM_SHOW_FSGROUP,
193                     "get_filesys_by_label", modify);
194     } else if (!strcmp(type, "Printer") ||
195                !strcmp(type2, "lpr Data")) {
196         DoReference(name, "select_printer", MM_MOD_PCAP, MM_SHOW_PCAP,
197                     "get_printcap_entry", modify);
198     } else if (!strcmp(type, "Service")) {
199         DoReference(name, "select_service", MM_MOD_SERVICE, MM_SHOW_SERVICE,
200                     "get_server_info", modify);
201 /* This code isn't complete, and it's not clear that we really want it...
202     } else if (!strcmp(type, "Packname")) {
203         char name2[256];
204         sprintf(name2, "%s:%s", type2, name);
205         p = strrchr(name2, '/');
206         if (p) *p = 0;
207         DoReference(name, "select_nfs", MM_MOD_NFS, MM_SHOW_NFS,
208                     "get_nfsphys", modify);
209 */  } else {
210         XBell(XtDisplay(w), 100);
211     }
212     XtFree(log);
213 }
214
215
216 /* This is the heart of handling the reference once we have found out
217  * what type of reference it is.
218  */
219
220 static DoReference(name, formname, modop, showop, query, modify)
221 char *name;
222 char *formname;
223 int modop;
224 int showop;
225 char *query;
226 int modify;
227 {
228     EntryForm *form, f;
229     MenuItem m;
230     char *argv[2], **aargv;
231     int status;
232
233     if (modify) {
234         form = GetAndClearForm(formname);
235         StoreField(form, 0, name);
236         form->menu = &m;
237         m.operation = modop;
238         m.query = query;
239         m.argc = 1;
240         if (showop == MM_SHOW_FSGROUP) {
241             DisplayForm(form);
242             MoiraValueChanged(form, form->inputlines[0]);
243         } else
244           MoiraFormApply(0, form);
245     } else {
246         f.menu = &m;
247         if (showop == MM_SHOW_FILSYS ||
248             showop == MM_SHOW_FSGROUP) f.extrastuff = (caddr_t) sq_create();
249         argv[0] = name;
250         m.operation = showop;
251         status = MoiraQuery(query, 1, argv, DisplayCallback, &f);
252         if (showop == MM_SHOW_FILSYS ||
253             showop == MM_SHOW_FSGROUP) {
254             while (sq_get_data(f.extrastuff, &aargv)) {
255                 ShowFilsys(aargv);
256             }
257             sq_destroy(f.extrastuff);
258         }
259         if (status)
260           com_err(program_name, status, " while looking up data");
261         else
262           AppendToLog("\n");
263     }
264 }
265
266
267 /*
268 ** PopupErrorMessage(text)
269 **
270 ** Given a char* pointing to an error message, possibly with imbedded
271 ** newlines, display the text in a popup window and put two buttons
272 ** at the bottom of the window, labelled "OK" and "Cancel."  Pop down
273 ** when one of the buttons is pressed.
274 **
275 ** Return 0 if "OK" is pressed, 1 for "Cancel."
276 */
277
278 Boolean
279 PopupErrorMessage(text, extrahelp)
280 char    *text;
281 char    *extrahelp;
282 {
283         static Widget           child;
284         Arg             wargs[10];
285         int             n;
286         static XmString        label;
287
288         if (tty) {
289             printf("%s\r\n", text);
290             return;
291         }
292
293         if (label) {
294                 XtFree(label);
295                 XtDestroyWidget(child);
296         }
297
298
299         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
300
301         n = 0;
302         XtSetArg(wargs[n], XmNmessageString, label);            n++;
303
304         child = (Widget) XmCreateErrorDialog(logwidget, "errormessage", wargs, n);
305         if (extrahelp) 
306                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, extrahelp);
307         else
308                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
309         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
310         XtManageChild(child);
311 }
312
313 /*
314 ** PopupHelpWindow(text)
315 **
316 ** Given a char* pointing to an help message, possibly with imbedded
317 ** newlines, display the text in a popup window and put a single button
318 ** at the bottom of the window, labelled "OK."  Pop down when the
319 ** the buttons is pressed.
320 */
321
322 void
323 PopupHelpWindow(text)
324 char    *text;
325 {
326         static Widget           child;
327         Arg             wargs[10];
328         int             n;
329
330         static XmString        label;
331         if (label) {
332                 XtFree(label);
333                 XtDestroyWidget(child);
334         }
335
336         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
337
338         n = 0;
339         XtSetArg(wargs[n], XmNmessageString, label);            n++;
340
341         child = (Widget) XmCreateMessageDialog(logwidget, "helpmessage", wargs, n);
342         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
343         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
344
345         XtManageChild(child);
346 }
347
348 /*
349 ** Given a char* to a single line of text, append this line at the bottom
350 ** of the log window.  Return 0 of the append was sucessful, non-zero
351 ** for an error condition.
352 */
353
354 int
355 AppendToLog(text)
356 char    *text;
357 {
358         XmTextPosition  pos;
359         char            *string, *p;
360
361         if (tty) {
362             fputs(text, stdout);
363             return;
364         }
365
366         string = XmTextGetString(logwidget);
367         pos = strlen(string);
368         XtFree(string);
369
370         XmTextReplace(logwidget, pos, pos, text);
371         XmTextSetCursorPosition(logwidget, pos + strlen(text));
372         if (pos > resources.maxlogsize) {
373             for (p = &string[pos-resources.maxlogsize]; *p && *p != '\n'; p++);
374             if (*p)
375               pos = p - string;
376             XmTextReplace(logwidget, 0, pos, "");
377         }
378 }
379
380 void
381 MakeWatchCursor(topW)
382 Widget  topW;
383 {
384     static Cursor mycursor = NULL;
385     EntryForm **fp;
386
387     if (!topW)
388       return;
389
390     if (!mycursor)
391       mycursor = XCreateFontCursor (XtDisplay(topW), XC_watch);
392
393     XDefineCursor(XtDisplay(topW), XtWindow(topW), mycursor);
394     for (fp = MoiraForms; *fp; fp++)
395       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
396         XDefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer), mycursor);
397 }
398
399 void
400 MakeNormalCursor(topW)
401 Widget  topW;
402 {
403     EntryForm **fp;
404
405     if (!topW)
406       return;
407
408     XUndefineCursor(XtDisplay(topW), XtWindow(topW));
409     for (fp = MoiraForms; *fp; fp++)
410       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
411         XUndefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer));
412 }
413
414 /*
415 ** Move through the fields of the spec and make certain that the
416 ** form's widgets actually reflect the current values.
417 */
418
419 void
420 UpdateForm(spec)
421 EntryForm       *spec;
422 {
423         UserPrompt      **myinputlines = spec->inputlines;
424         UserPrompt      *current;
425         Arg             wargs[10];
426         int             n, kidcount;
427         Widget          kid;
428
429         if (tty || spec->formpointer == NULL) return;
430
431         for (   current = (*myinputlines);
432                 current; 
433                 myinputlines++, current = (*myinputlines)) {
434
435                 if (current->changed) {
436                     n = 0;
437                     XtSetArg(wargs[n], XmNsensitive,
438                              current->insensitive ? False : True); n++;
439                     XtSetValues(current->mywidget, wargs, n);
440                     current->changed = False;
441                 }
442
443                 switch (current->type) {
444                 case FT_STRING:
445                         if (current->returnvalue.stringvalue) {
446                                 XmTextSetString (current->mywidget, current->returnvalue.stringvalue);
447                         }
448                         break;
449
450                 case FT_BOOLEAN:
451                         n = 0;
452                         XtSetArg(wargs[n], XmNset,
453                                  current->returnvalue.booleanvalue ? True : False);     n++;
454                         XtSetValues (current->mywidget, wargs, n);
455                         break;
456
457                 case FT_KEYWORD:
458                         kidcount = NumChildren(current->mywidget);
459                         while(kidcount--) {
460                                 n = 0;
461                                 kid = NthChild(current->mywidget, kidcount);
462                                 if (current->returnvalue.stringvalue &&
463                                         (!strcmp (XtName(kid), current->returnvalue.stringvalue))) {
464                                         XtSetArg(wargs[n], XmNset, True);
465                                         n++;
466                                 }
467                                 else {
468                                         XtSetArg(wargs[n], XmNset, False);
469                                         n++;
470                                 }
471                                 XtSetValues (kid, wargs, n);
472                         }
473                         break;
474
475                 case FT_NUMBER:
476                         break;
477                 }
478                 n = 0;
479                 XtSetArg(wargs[n], XtNsensitive, !(current->insensitive));              n++;
480                 XtSetValues (current->mywidget, wargs, n);
481         }
482 }
483
484 void
485 extra_help_callback(w, client_data, call_data)
486 Widget  w;
487 char    *client_data;
488 XmAnyCallbackStruct     *call_data;
489 {
490     help(client_data);
491 }
492
493
494 int write_log_to_file(fn)
495 char *fn;
496 {
497     char *string, buf[256];
498     int fd, i;
499     extern int errno;
500
501     string = XmTextGetString(logwidget);
502     fd = open(fn, O_WRONLY|O_CREAT, 0666);
503     if (fd < 0) {
504         sprintf(buf, "opening output file \"%s\"", fn);
505         com_err(program_name, errno, buf);
506         return(1);
507     }
508     if ((i = write(fd, string, strlen(string))) < 0) {
509         sprintf(buf, "writing output file \"%s\"", fn);
510         com_err(program_name, errno, buf);
511         return(1);
512     }
513     if ((i = close(fd)) < 0) {
514         sprintf(buf, "closing output file \"%s\"", fn);
515         com_err(program_name, errno, buf);
516         return(1);
517     }
518     return(0);
519 }
520
521
522 void yesCallback(w, ret, dummy)
523 Widget w;
524 XtPointer ret;
525 XtPointer dummy;
526 {
527     int *ip = (int *)ret;
528     *ip = 1;
529 }
530
531 void noCallback(w, ret, dummy)
532 Widget w;
533 XtPointer ret;
534 XtPointer dummy;
535 {
536     int *ip = (int *)ret;
537     *ip = -1;
538 }
539
540
541 static int value;
542 static XtCallbackRec yescb[] = { { yesCallback, (XtPointer) &value },
543                                  { NULL, NULL} };
544 static XtCallbackRec nocb[]  = { { noCallback, (XtPointer) &value },
545                                  {NULL, NULL} };
546
547 Boolean AskQuestion(text, helpname)
548 char *text, *helpname;
549 {
550         static Widget           child;
551         Arg             wargs[10];
552         int             n;
553         static XmString        label, yes = NULL, no;
554         XEvent  event;
555         XtAppContext _XtDefaultAppContext();
556
557         if (tty) {
558             char buf[256];
559
560             while (1) {
561                 printf("%s (Y/N) ", text);
562                 fflush(stdout);
563                 if (mgets(buf, sizeof(buf)))
564                   return(False);
565                 if (buf[0] == 'T' || buf[0] == 't' ||
566                     buf[0] == 'Y' || buf[0] == 'y')
567                   return(True);
568                 else if (buf[0] == 'F' || buf[0] == 'f' ||
569                          buf[0] == 'N' || buf[0] == 'n')
570                   return(False);
571                 printf("Please answer Yes or No\r\n");
572             }
573         }
574
575         if (!yes) {
576             yes = XmStringCreate("Yes", XmSTRING_DEFAULT_CHARSET);
577             no = XmStringCreate("No", XmSTRING_DEFAULT_CHARSET);
578         }
579         if (label) {
580                 XtFree(label);
581                 XtDestroyWidget(child);
582         }
583
584         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
585
586         n = 0;
587         XtSetArg(wargs[n], XmNmessageString, label);            n++;
588         XtSetArg(wargs[n], XmNokLabelString, yes);              n++;
589         XtSetArg(wargs[n], XmNcancelLabelString, no);           n++;
590         XtSetArg(wargs[n], XmNokCallback, yescb);               n++;
591         XtSetArg(wargs[n], XmNcancelCallback, nocb);            n++;
592
593         child = (Widget) XmCreateQuestionDialog(logwidget, "question", wargs, n);
594         if (helpname) 
595                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, helpname);
596         else
597                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
598
599         XtManageChild(child);
600         value = 0;
601         while (value == 0) {
602             XtAppNextEvent(_XtDefaultAppContext(), &event);
603             XtDispatchEvent(&event);
604         }
605         if (value > 0)
606           return(1);
607         else
608           return(0);
609 }
610
611
612
613 /******* temporary ********/
614 display_error(msg)
615 char *msg;
616 {
617     PopupErrorMessage(msg, "no_more_help");
618 }
This page took 0.09078 seconds and 5 git commands to generate.