1 /*****************************************************************************
2 ** File : doubleclick.c **
3 ** Purpose : Initialise and Realise double click dialog options **
4 ** Author : Jonathan Abbey ARL:UT **
5 ** Date : Aug 1991 **
6 ** Documentation : Xdtm Design Folder **
7 ** Related Files : **
8 ** Changes : 18-04-92, Edward Groenendaal **
9 ** Added #if NeedFunctionPrototypes stuff **
10 ** 25-05-92, Edward Groenendaal **
11 ** Added support for multiple instances **
12 ** June 20, 1992, Ramon Santiago **
13 ** Changed all XtCreate calls to XtVaCreate calls. **
14 ** Changed all caddr_t to XtPointer. **
15 ** Removed some lint. **
16 ** Modified some variable names, and moved language **
17 ** specific strings to app-defaults file. **
18 ****************************************************************************/
19
20 /*
21 #define DEBUG 1
22 */
23
24 #include "xdtm.h"
25 #include "menus.h"
26 #include "parse.h" /* AppProgram, etc. */
27 #include "Ext/appl.h"
28 #include <X11/Shell.h>
29 #include <X11/Xaw/Label.h>
30 #include <X11/Xaw/Command.h>
31 #include <X11/Xaw/AsciiText.h>
32 #include "Xedw/XedwForm.h"
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <sys/time.h>
37 #include <grp.h>
38 #include <sys/param.h>
39 #include <pwd.h>
40 #include <unistd.h> /* for R_OK */
41 #ifdef alliant
42 #include <a.out.h> /* Alliant FX series magic number file */
43 #endif
44
45 #ifndef NGROUPS
46 #define NGROUPS 255 /* Number of groups */
47 #endif
48
49 /* current_mode controls the icon display in the display manager.
50 We need to change it so that we can get an icon in our
51 doubleclick dialog box even if the display manager is in
52 non-icon mode. */
53
54 extern Icon_mode current_mode;
55
56 /* The Filestatus structure is used to keep track of
57 elements of filestat that the user is capable of
58 changing through the doubleclick dialog box. */
59
60 typedef struct filestatus {
61 u_short mode;
62 char filename[80];
63 char owner[16];
64 char group[16];
65 } Filestatus;
66
67 /* applist is a linked list of nodes that keep track of information for
68 process started from the doubleclick requester. */
69
70 typedef struct appnode {
71 AppProgram node;
72 struct appnode *next;
73 } AppNode;
74
75
76 /* #define's for undo_func() */
77
78 #define RESET 0
79 #define UNDO 1
80
81 /* #define's for update_buttons() */
82
83 #define INIT 0
84 #define UNDO 1
85 #define UPDATE 2
86 #define TEMP 3
87
88 /* Translation table for text widgets */
89
90 static char textWidgetTranslations [] = "#override\n\
91 <Key>Return : no-op(RingBell)\n\
92 <Key>Up : no-op()\n\
93 <Key>Down : no-op()\n\
94 <Key>space : no-op(RingBell)\n\
95 <Btn1Motion> : no-op()\n\
96 <Btn2Down> : no-op()\n\
97 <Btn3Down> : no-op()\n\
98 <Btn3Motion> : no-op()\n\
99 <Btn3Up> : no-op()\n\
100 <Btn1Up> : no-op()"; /* If we can't have a mac, then we can't have
101 any sort of drag selection at all. It just
102 confuses our users. */
103
104 XtTranslations textWidgettranslations;
105
106 XawTextSelectType no_extended_select [] = {XawselectPosition,XawselectNull};
107
108 /* Define permission bits */
109
110 #define IREAD 0400
111 #define IWRITE 0200
112 #define IEXEC 0100
113 #define GREAD 0040
114 #define GWRITE 0020
115 #define GEXEC 0010
116 #define AREAD 0004
117 #define AWRITE 0002
118 #define AEXEC 0001
119
120 /* Button indices */
121
122 #define FIRSTBUTTON 0
123 #define LASTBUTTON 11
124
125 typedef enum {
126 rown = 0, rgrp, roth, wown, wgrp, woth, xown, xgrp, xoth,
127 uid_but, gid_but, stky_but
128 } Buttons;
129
130 struct buttontype {
131 u_short bitmask;
132 Widget widget;
133 int state;
134 };
135
136 /* SetButton (button_enum) -- sets the bitmap imagery for the widget
137 corresponding to the enum index b, according to the bit in filestat.st_mode
138 defined in button[]. */
139
140 #define SetButton(b) \
141 { \
142 XtVaSetValues( \
143 current->button[b].widget, \
144 XtNbitmap, (current->filestat.st_mode & current->button[b].bitmask) ? tick : emptytick, \
145 NULL ) ; \
146 current->button[b].state = (current->filestat.st_mode & current->button[b].bitmask); \
147 }
148
149
150 typedef struct fileinfo {
151 /* Used for callbacks */
152 int mode;
153
154 /* Data about instance */
155 struct stat filestat;
156 AppNode *applist;
157 Filestatus laststat;
158 Filestatus oldstat;
159 char *filedate; /* 26 */
160 char *filesize; /* 10 */
161 XdtmList *xdtmlist_element;
162 char *edit_filename; /* 255 */
163 char *edit_owner; /* 255 */
164 char *edit_group; /* 255 */
165 char *dc_fullname; /* 255 */
166 char *dc_filename; /* 255 */
167 char *dc_path; /* 255 */
168 char *eb_input; /* 255 */
169 char *eb_output; /* 255 */
170 char *eb_error; /* 255 */
171 int file_editable; /* FALSE */
172 int file_edited; /* FALSE */
173
174 /* Widgets */
175 Widget fileInfoDialog;
176 Widget form;
177 Widget form1;
178 Widget form1a;
179 Widget form1b;
180 Widget form1c;
181 Widget form2;
182 Widget form2a;
183 Widget form2a1;
184 Widget form2a2;
185 Widget form2a3;
186 Widget form2a4;
187 Widget form2a5;
188 Widget form2a6;
189 Widget form2b;
190 Widget form3;
191
192
193 /* form 1a widgets */
194
195 Widget form1a_label_icon;
196 Widget form1a_text_filename;
197 Widget form1a_text_filename_src;
198
199 /* form 1b widgets */
200
201 Widget form1b_label_date;
202 Widget form1b_label_size;
203 Widget form1b_label_datelabel;
204 Widget form1b_label_sizelabel;
205
206 /* form 1c widgets */
207
208 Widget form1c_label_owner;
209 Widget form1c_text_owner;
210 Widget form1c_text_owner_src;
211 Widget form1c_label_group;
212 Widget form1c_text_group;
213 Widget form1c_text_group_src;
214
215 /* form2a widgets */
216
217 Widget form2a_label_permissions;
218
219 Widget form2a1_label_blank;
220 Widget form2a1_label_owner;
221 Widget form2a1_label_group;
222 Widget form2a1_label_other;
223
224 Widget form2a2_label_read;
225 Widget form2a2_button_rown;
226 Widget form2a2_button_rgrp;
227 Widget form2a2_button_roth;
228
229 Widget form2a3_label_write;
230 Widget form2a3_button_wown;
231 Widget form2a3_button_wgrp;
232 Widget form2a3_button_woth;
233
234 Widget form2a4_label_exec;
235 Widget form2a4_button_xown;
236 Widget form2a4_button_xgrp;
237 Widget form2a4_button_xoth;
238
239 Widget form2a5_label_blank;
240 Widget form2a5_label_setuid;
241 Widget form2a5_label_setgid;
242 Widget form2a5_label_sticky;
243
244 Widget form2a6_label_blank;
245 Widget form2a6_button_setuid;
246 Widget form2a6_button_setgid;
247 Widget form2a6_button_sticky;
248
249 /* form 2b widgets */
250
251 Widget form2b_command_update;
252 Widget form2b_command_undo;
253 Widget form2b_command_reset;
254
255 /* form3 command widgets */
256
257 Widget form3_command_done;
258 Widget form3_command_view;
259 Widget form3_command_edit;
260 Widget form3_command_execwin;
261 Widget form3_command_execback;
262 Widget form3_command_help;
263
264 /* Execute in background popup */
265
266 Widget eb_popup;
267 Widget ebform;
268 Widget ebform1;
269 Widget ebform2;
270 Widget eblabeltitle;
271 Widget eblabelsubtitle;
272 Widget eblabelinput;
273 Widget eblabeloutput;
274 Widget eblabelerror;
275 Widget ebtextinput;
276 Widget ebtextoutput;
277 Widget ebtexterror;
278 Widget ebcommandcancel;
279 Widget ebcommandok;
280
281 /* Verify Quit Popup */
282
283 Widget verify_popup;
284 Widget verify_form;
285 Widget verify_label;
286 Widget verify_yes;
287 Widget verify_no;
288 Widget verify_cancel;
289
290 struct buttontype button[LASTBUTTON+1];
291 } Fileinfo;
292
293 typedef struct {
294 Fileinfo *fileinfo;
295 int mode;
296 Buttons select;
297 } InfoButtons;
298
299 typedef struct fileinfoelement {
300 Fileinfo *fileinfo;
301 struct fileinfoelement *next;
302 } Fileinfoelement;
303
304 Fileinfoelement *Fileinfolist;
305
306 Widget toplevel;
307
308 /* external and forward functions definitions */
309 #if NeedFunctionPrototypes
310 void cancel_func(Widget, XtPointer, XtPointer);
311 private AppProgram *compute_appnode(String, Fileinfo*);
312 void dcbutton_toggled(Widget, InfoButtons *, XtPointer);
313 void destroy_doubleclick_dialog(Widget, Fileinfo *, XtPointer);
314 extern Boolean directoryManagerNewDirectory(String);
315 extern void displayfile(String, String, String, XtGrabKind);
316 extern void editfile(String);
317 void execback_popdown(Widget, InfoButtons *, XtPointer);
318 void execback_realize(Widget, Fileinfo *, XtPointer);
319 public int execute (String, String, String, Boolean, AppProgram *);
320 void execwin_func(Widget, Fileinfo *, XtPointer);
321 void free_info(Widget, InfoButtons *, XtPointer);
322 extern Boolean getIconType(String, String, XdtmList *);
323 int group_number(char *);
324 void help_func(Widget, XtPointer, XtPointer);
325 public void ioerr_dialog(int);
326 private void load_text(Widget, char *);
327 public void popup_verify_app(AppProgram *);
328 public void realize_dialog(Widget, Widget, XtGrabKind, XtEventHandler, XtPointer);
329 public void run_app(AppProgram *, char *, char *, char *);
330 extern void setCursor(Cursor);
331 private void set_icon(Fileinfo*);
332 private void set_size_date(Fileinfo*);
333 void text_callback(Widget, Fileinfo *, XtPointer);
334 void verify_callback(Widget, Fileinfo *, XtPointer);
335 void undo_func(Widget, InfoButtons*, XtPointer);
336 private void update_buttons(int, Fileinfo*);
337 void update_func(Widget, Fileinfo *, XtPointer);
338 int user_is_member(gid_t);
339 void view_func(Widget, Fileinfo *, XtPointer);
340 #else
341 void cancel_func();
342 private AppProgram *compute_appnode();
343 void dcbutton_toggled();
344 void destroy_doubleclick_dialog();
345 extern Boolean directoryManagerNewDirectory();
346 extern void displayfile();
347 extern void editfile();
348 void execback_popdown();
349 void execback_realize();
350 public int execute ();
351 void execwin_func();
352 void free_info();
353 extern Boolean getIconType();
354 int group_number();
355 void help_func();
356 public void ioerr_dialog();
357 private void load_text();
358 public void popup_verify_app();
359 public void realize_dialog();
360 public void run_app();
361 extern void setCursor();
362 private void set_icon();
363 private void set_size_date();
364 void text_callback();
365 void verify_callback();
366 void undo_func();
367 private void update_buttons();
368 void update_func();
369 int user_is_member();
370 void view_func();
371 #endif
372
373 /*****************************************************************************
374 * init_doubleclick_dialog *
375 *****************************************************************************/
init_doubleclick(top)376 public void init_doubleclick(top)
377 Widget top;
378 {
379 /* Not much to do here now.. just make sure we've got the top Widget ready
380 * for later;
381 */
382 toplevel = top;
383 Fileinfolist = NULL;
384 }
385
386 /*****************************************************************************
387 * create_doubleclick *
388 *****************************************************************************/
create_doubleclick()389 public Fileinfo *create_doubleclick()
390 {
391 Fileinfo *current;
392 InfoButtons *infobutton;
393
394 static String permLabel = "Permissions";
395 static String readLabel = "Read";
396 static String writeLabel = "Write";
397 static String execLabel = "Execute";
398 static String ownerLabel = "Owner";
399 static String groupLabel = "Group";
400 static String otherLabel = "Other";
401
402 /* OK lets create a new Fileinfo */
403 if (Fileinfolist == NULL) {
404 /* List is empty */
405 Fileinfolist = (Fileinfoelement*) XtMalloc(sizeof(Fileinfoelement));
406 current = Fileinfolist->fileinfo = (Fileinfo*) XtMalloc(sizeof(Fileinfo));
407 Fileinfolist->next = NULL;
408 } else {
409 /* Find end of list */
410 Fileinfoelement *p = Fileinfolist;
411 while (p->next != NULL)
412 p = p->next;
413 p->next = (Fileinfoelement*) XtMalloc(sizeof(Fileinfoelement));
414 current = p->next->fileinfo = (Fileinfo*) XtMalloc(sizeof(Fileinfo));
415 p->next->next = NULL;
416 }
417
418 /* Initialise Fileinfo structure */
419 current->filedate = (char*) XtMalloc(sizeof(char)*26);
420 current->filesize = (char*) XtMalloc(sizeof(char)*10);
421 current->edit_filename = (char*) XtMalloc(sizeof(char)*255);
422 current->edit_owner = (char*) XtMalloc(sizeof(char)*255);
423 current->edit_group = (char*) XtMalloc(sizeof(char)*255);
424 current->dc_fullname = (char*) XtMalloc(sizeof(char)*255);
425 current->dc_filename = (char*) XtMalloc(sizeof(char)*255);
426 current->dc_path = (char*) XtMalloc(sizeof(char)*255);
427 current->eb_input = (char*) XtMalloc(sizeof(char)*255);
428 current->eb_output = (char*) XtMalloc(sizeof(char)*255);
429 current->eb_error = (char*) XtMalloc(sizeof(char)*255);
430 current->file_editable = FALSE;
431 current->file_edited = FALSE;
432 current->xdtmlist_element = (XdtmList*) XtMalloc(sizeof(XdtmList));
433
434 /* Purify complains about uninitialized memory read, so initialize... */
435 current->filedate[0] = 0;
436 current->filesize[0] = 0;
437 current->edit_filename[0] = 0;
438 current->edit_owner[0] = 0;
439 current->edit_group[0] = 0;
440 current->dc_fullname[0] = 0;
441 current->xdtmlist_element->string = NULL;
442 current->xdtmlist_element->icon = DUMMY;
443 current->xdtmlist_element->user_data = NULL;
444
445 textWidgettranslations = XtParseTranslationTable(textWidgetTranslations);
446
447 /* Create main doubleclick pop-up shell widget */
448
449 current->fileInfoDialog =
450 XtVaCreatePopupShell(
451 "fileInfoDialog",
452 transientShellWidgetClass,
453 toplevel,
454 NULL ) ;
455
456 /* Create main form widget for popup */
457
458 current->form =
459 XtVaCreateManagedWidget(
460 "form",
461 xedwFormWidgetClass,
462 current->fileInfoDialog,
463 NULL ) ;
464
465 /* Form 1 */
466
467 current->form1 =
468 XtVaCreateManagedWidget(
469 "form1",
470 xedwFormWidgetClass,
471 current->form,
472 XtNborderWidth, 1,
473 XtNfullWidth, True,
474 XtNresizable, True,
475 NULL ) ;
476
477 /* Form 1a */
478
479 current->form1a =
480 XtVaCreateManagedWidget(
481 "form1a",
482 xedwFormWidgetClass,
483 current->form1,
484 XtNfullHeight, True,
485 XtNfullWidth, False,
486 XtNborderWidth, 0,
487 XtNresizable, True,
488 NULL ) ;
489
490 /** Widgets for Form 1a **/
491
492 current->form1a_label_icon =
493 XtVaCreateManagedWidget(
494 "form1a_label_icon",
495 labelWidgetClass,
496 current->form1a,
497 XtNborderWidth, 0,
498 NULL ) ;
499
500 current->form1a_text_filename =
501 XtVaCreateManagedWidget(
502 "form1a_text_filename",
503 asciiTextWidgetClass,
504 current->form1a,
505 XtNborderWidth, 1,
506 XtNfromVert, current->form1a_label_icon,
507 XtNstring, current->edit_filename,
508 XtNeditType, XawtextEdit,
509 XtNselectTypes, no_extended_select,
510 XtNlength, 255,
511 XtNuseStringInPlace, True,
512 NULL ) ;
513
514 XtVaGetValues(
515 current->form1a_text_filename,
516 XtNtextSource, &(current->form1a_text_filename_src),
517 NULL ) ;
518
519 XtAddCallback(current->form1a_text_filename_src, XtNcallback,
520 (XtCallbackProc)text_callback, (XtPointer)current);
521 XtOverrideTranslations(current->form1a_text_filename,
522 textWidgettranslations);
523
524 /* Form 1b */
525
526 current->form1b =
527 XtVaCreateManagedWidget(
528 "form1b",
529 xedwFormWidgetClass,
530 current->form1,
531 XtNfullHeight, True,
532 XtNborderWidth, 0,
533 XtNfromHoriz, current->form1a,
534 XtNresizable, True,
535 NULL ) ;
536
537 /** Widgets for Form 1b **/
538
539 current->form1b_label_sizelabel =
540 XtVaCreateManagedWidget(
541 "form1b_label_sizelabel",
542 labelWidgetClass,
543 current->form1b,
544 XtNlabel, "File Size: ",
545 XtNborderWidth, 0,
546 NULL ) ;
547
548 current->form1b_label_size =
549 XtVaCreateManagedWidget(
550 "form1b_label_size",
551 labelWidgetClass,
552 current->form1b,
553 XtNlabel, current->filesize,
554 XtNborderWidth, 0,
555 XtNfromHoriz, current->form1b_label_sizelabel,
556 XtNjustify, XtJustifyLeft,
557 XtNinternalWidth, 0,
558 XtNresizable, True,
559 NULL ) ;
560
561 current->form1b_label_datelabel =
562 XtVaCreateManagedWidget(
563 "form1b_label_datelabel",
564 labelWidgetClass,
565 current->form1b,
566 XtNlabel, "File Date: ",
567 XtNborderWidth, 0,
568 XtNfromVert, current->form1b_label_sizelabel,
569 NULL ) ;
570
571 current->form1b_label_date =
572 XtVaCreateManagedWidget(
573 "form1b_label_date",
574 labelWidgetClass,
575 current->form1b,
576 XtNlabel, current->filedate,
577 XtNborderWidth, 0,
578 XtNfromVert, current->form1b_label_sizelabel,
579 XtNfromHoriz, current->form1b_label_datelabel,
580 XtNjustify, XtJustifyLeft,
581 XtNinternalWidth, 0,
582 NULL ) ;
583
584 /* Form 1c */
585
586 current->form1c =
587 XtVaCreateManagedWidget(
588 "form1b",
589 xedwFormWidgetClass,
590 current->form1,
591 XtNfullHeight, True,
592 XtNborderWidth, 0,
593 XtNfromHoriz, current->form1b,
594 XtNresizable, True,
595 NULL ) ;
596
597 /** Widgets for Form 1c **/
598
599 current->form1c_label_owner =
600 XtVaCreateManagedWidget(
601 "form1c_label_owner",
602 labelWidgetClass,
603 current->form1c,
604 XtNborderWidth, 0,
605 XtNlabel, "Owner:",
606 XtNjustify, XtJustifyRight,
607 NULL ) ;
608
609 current->form1c_text_owner =
610 XtVaCreateManagedWidget(
611 "form1c_text_owner",
612 asciiTextWidgetClass,
613 current->form1c,
614 XtNborderWidth, 1,
615 XtNfromHoriz, current->form1c_label_owner,
616 XtNstring, current->edit_owner,
617 XtNeditType, XawtextEdit,
618 XtNlength, 255,
619 XtNuseStringInPlace, True,
620 XtNselectTypes, no_extended_select,
621 NULL ) ;
622
623 XtVaGetValues(
624 current->form1c_text_owner,
625 XtNtextSource, &(current->form1c_text_owner_src),
626 NULL ) ;
627
628 XtAddCallback(current->form1c_text_owner_src, XtNcallback,
629 (XtCallbackProc)text_callback, (XtPointer)current);
630 XtOverrideTranslations(current->form1c_text_owner, textWidgettranslations);
631
632 current->form1c_label_group =
633 XtVaCreateManagedWidget(
634 "form1c_label_group",
635 labelWidgetClass,
636 current->form1c,
637 XtNborderWidth, 0,
638 XtNfromVert, current->form1c_label_owner,
639 XtNlabel, "Group:",
640 XtNjustify, XtJustifyRight,
641 NULL ) ;
642
643 current->form1c_text_group =
644 XtVaCreateManagedWidget(
645 "form1c_text_group",
646 asciiTextWidgetClass,
647 current->form1c,
648 XtNborderWidth, 1,
649 XtNfromHoriz, current->form1c_label_group,
650 XtNfromVert, current->form1c_text_owner,
651 XtNselectTypes, no_extended_select,
652 XtNstring, current->edit_group,
653 XtNeditType, XawtextEdit,
654 XtNlength, 255,
655 XtNuseStringInPlace, True,
656 NULL ) ;
657
658 XtVaGetValues(
659 current->form1c_text_group,
660 XtNtextSource, &(current->form1c_text_group_src),
661 NULL ) ;
662
663 XtAddCallback(current->form1c_text_group_src, XtNcallback,
664 (XtCallbackProc)text_callback, (XtPointer)current);
665 XtOverrideTranslations(current->form1c_text_group, textWidgettranslations);
666
667 /* Form 2 */
668
669 current->form2 =
670 XtVaCreateManagedWidget(
671 "form2",
672 xedwFormWidgetClass,
673 current->form,
674 XtNfullWidth, True,
675 XtNfromVert, current->form1,
676 XtNborderWidth, 0,
677 NULL ) ;
678
679 /** Widgets for Form 2 **/
680
681 current->form2a =
682 XtVaCreateManagedWidget(
683 "form2a",
684 xedwFormWidgetClass,
685 current->form2,
686 XtNfullHeight, True,
687 XtNborderWidth, 1,
688 NULL ) ;
689
690 /** Widgets for Form 2a */
691
692 current->form2a_label_permissions =
693 XtVaCreateManagedWidget(
694 "form2a_label_permissions",
695 labelWidgetClass,
696 current->form2a,
697 XtNlabel, permLabel,
698 XtNborderWidth, 0,
699 XtNfullWidth, True,
700 NULL );
701
702 /* Form 2a1 */
703
704 current->form2a1 =
705 XtVaCreateManagedWidget(
706 "form2a1",
707 xedwFormWidgetClass,
708 current->form2a,
709 XtNborderWidth, 0,
710 XtNfromVert, current->form2a_label_permissions,
711 NULL ) ;
712
713 /** Widgets for Form 2a1 **/
714
715 current->form2a1_label_blank =
716 XtVaCreateManagedWidget(
717 "form2a1_label_blank",
718 labelWidgetClass,
719 current->form2a1,
720 XtNlabel, " ", /* Empty label to hold space in form */
721 XtNborderWidth, 0,
722 NULL ) ;
723
724 current->form2a1_label_owner =
725 XtVaCreateManagedWidget(
726 "form2a1_label_owner",
727 labelWidgetClass,
728 current->form2a1,
729 XtNlabel, ownerLabel,
730 XtNfromVert, current->form2a1_label_blank,
731 XtNborderWidth, 0,
732 NULL ) ;
733
734 current->form2a1_label_group =
735 XtVaCreateManagedWidget(
736 "form2a1_label_owner",
737 labelWidgetClass,
738 current->form2a1,
739 XtNlabel, groupLabel,
740 XtNfromVert, current->form2a1_label_owner,
741 XtNborderWidth, 0,
742 NULL ) ;
743
744 current->form2a1_label_other =
745 XtVaCreateManagedWidget(
746 "form2a1_label_other",
747 labelWidgetClass,
748 current->form2a1,
749 XtNlabel, otherLabel,
750 XtNborderWidth, 0,
751 XtNfromVert, current->form2a1_label_group,
752 NULL ) ;
753
754 /* Form 2a2 */
755
756 current->form2a2 =
757 XtVaCreateManagedWidget(
758 "form2a2",
759 xedwFormWidgetClass,
760 current->form2a,
761 XtNfromHoriz, current->form2a1,
762 XtNfromVert, current->form2a_label_permissions,
763 XtNborderWidth, 0,
764 NULL ) ;
765
766 /** Widgets for Form 2a2 **/
767
768 current->form2a2_label_read =
769 XtVaCreateManagedWidget(
770 "form2a2_label_read",
771 labelWidgetClass,
772 current->form2a2,
773 XtNlabel, readLabel,
774 XtNborderWidth, 0,
775 XtNjustify, XtJustifyLeft,
776 XtNinternalWidth, 0,
777 NULL ) ;
778
779 current->form2a2_button_rown =
780 XtVaCreateManagedWidget(
781 "form2a2_button_rown",
782 commandWidgetClass,
783 current->form2a2,
784 XtNfromVert, current->form2a2_label_read,
785 NULL ) ;
786
787 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
788 infobutton->fileinfo = current;
789 infobutton->select = rown;
790 XtAddCallback(current->form2a2_button_rown, XtNcallback,
791 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
792 XtAddCallback(current->form2a2_button_rown, XtNdestroyCallback,
793 (XtCallbackProc)free_info, (XtPointer)infobutton);
794
795 current->form2a2_button_rgrp =
796 XtVaCreateManagedWidget(
797 "form2a2_button_rgrp",
798 commandWidgetClass,
799 current->form2a2,
800 XtNfromVert, current->form2a2_button_rown,
801 NULL ) ;
802
803 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
804 infobutton->fileinfo = current;
805 infobutton->select = rgrp;
806 XtAddCallback(current->form2a2_button_rgrp, XtNcallback,
807 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
808 XtAddCallback(current->form2a2_button_rgrp, XtNdestroyCallback,
809 (XtCallbackProc)free_info, (XtPointer)infobutton);
810
811 current->form2a2_button_roth =
812 XtVaCreateManagedWidget(
813 "form2a2_button_roth",
814 commandWidgetClass,
815 current->form2a2,
816 XtNfromVert, current->form2a2_button_rgrp,
817 NULL ) ;
818
819 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
820 infobutton->fileinfo = current;
821 infobutton->select = roth;
822 XtAddCallback(current->form2a2_button_roth, XtNcallback,
823 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
824 XtAddCallback(current->form2a2_button_roth, XtNdestroyCallback,
825 (XtCallbackProc)free_info, (XtPointer)infobutton);
826
827 /* Form 2a3 */
828
829 current->form2a3 =
830 XtVaCreateManagedWidget(
831 "form2a3",
832 xedwFormWidgetClass,
833 current->form2a,
834 XtNfromHoriz, current->form2a2,
835 XtNfromVert, current->form2a_label_permissions,
836 XtNborderWidth, 0,
837 NULL ) ;
838
839 /** Widgets for Form 2a3 **/
840
841 current->form2a3_label_write =
842 XtVaCreateManagedWidget(
843 "form2a3_label_write",
844 labelWidgetClass,
845 current->form2a3,
846 XtNlabel, writeLabel,
847 XtNjustify, XtJustifyLeft,
848 XtNborderWidth, 0,
849 XtNinternalWidth, 0,
850 NULL ) ;
851
852 current->form2a3_button_wown =
853 XtVaCreateManagedWidget(
854 "form2a3_button_wown",
855 commandWidgetClass,
856 current->form2a3,
857 XtNfromVert, current->form2a3_label_write,
858 NULL ) ;
859
860 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
861 infobutton->fileinfo = current;
862 infobutton->select = wown;
863 XtAddCallback(current->form2a3_button_wown, XtNcallback,
864 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
865 XtAddCallback(current->form2a3_button_wown, XtNdestroyCallback,
866 (XtCallbackProc)free_info, (XtPointer)infobutton);
867
868 current->form2a3_button_wgrp =
869 XtVaCreateManagedWidget(
870 "form2a3_button_wgrp",
871 commandWidgetClass,
872 current->form2a3,
873 XtNfromVert, current->form2a3_button_wown,
874 NULL ) ;
875
876 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
877 infobutton->fileinfo = current;
878 infobutton->select = wgrp;
879 XtAddCallback(current->form2a3_button_wgrp, XtNcallback,
880 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
881 XtAddCallback(current->form2a3_button_wgrp, XtNdestroyCallback,
882 (XtCallbackProc)free_info, (XtPointer)infobutton);
883
884 current->form2a3_button_woth =
885 XtVaCreateManagedWidget(
886 "form2a3_button_woth",
887 commandWidgetClass,
888 current->form2a3,
889 XtNfromVert, current->form2a3_button_wgrp,
890 NULL ) ;
891
892 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
893 infobutton->fileinfo = current;
894 infobutton->select = woth;
895 XtAddCallback(current->form2a3_button_woth, XtNcallback,
896 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
897 XtAddCallback(current->form2a3_button_woth, XtNdestroyCallback,
898 (XtCallbackProc)free_info, (XtPointer)infobutton);
899
900 /* Form 2a4 */
901
902 current->form2a4 =
903 XtVaCreateManagedWidget(
904 "form2a4",
905 xedwFormWidgetClass,
906 current->form2a,
907 XtNfromHoriz, current->form2a3,
908 XtNfromVert, current->form2a_label_permissions,
909 XtNborderWidth, 0,
910 NULL ) ;
911
912 /** Widgets for Form 2a4 **/
913
914 current->form2a4_label_exec =
915 XtVaCreateManagedWidget(
916 "form2a4_label_exec",
917 labelWidgetClass,
918 current->form2a4,
919 XtNlabel, execLabel,
920 XtNborderWidth, 0,
921 XtNjustify, XtJustifyLeft,
922 XtNinternalWidth, 0,
923 NULL ) ;
924
925 current->form2a4_button_xown =
926 XtVaCreateManagedWidget(
927 "form2a4_button_xown",
928 commandWidgetClass,
929 current->form2a4,
930 XtNfromVert, current->form2a4_label_exec,
931 NULL ) ;
932
933 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
934 infobutton->fileinfo = current;
935 infobutton->select = xown;
936 XtAddCallback(current->form2a4_button_xown, XtNcallback,
937 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
938 XtAddCallback(current->form2a4_button_xown, XtNdestroyCallback,
939 (XtCallbackProc)free_info, (XtPointer)infobutton);
940
941 current->form2a4_button_xgrp =
942 XtVaCreateManagedWidget(
943 "form2a4_button_xgrp",
944 commandWidgetClass,
945 current->form2a4,
946 XtNfromVert, current->form2a4_button_xown,
947 NULL ) ;
948
949 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
950 infobutton->fileinfo = current;
951 infobutton->select = xgrp;
952 XtAddCallback(current->form2a4_button_xgrp, XtNcallback,
953 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
954 XtAddCallback(current->form2a4_button_xgrp, XtNdestroyCallback,
955 (XtCallbackProc)free_info, (XtPointer)infobutton);
956
957 current->form2a4_button_xoth =
958 XtVaCreateManagedWidget(
959 "form2a4_button_xoth",
960 commandWidgetClass,
961 current->form2a4,
962 XtNfromVert, current->form2a4_button_xgrp,
963 NULL ) ;
964
965 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
966 infobutton->fileinfo = current;
967 infobutton->select = xoth;
968 XtAddCallback(current->form2a4_button_xoth, XtNcallback,
969 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
970 XtAddCallback(current->form2a4_button_xoth, XtNdestroyCallback,
971 (XtCallbackProc)free_info, (XtPointer)infobutton);
972
973 /* Form 2a5 */
974
975 current->form2a5 =
976 XtVaCreateManagedWidget(
977 "form2a5",
978 xedwFormWidgetClass,
979 current->form2a,
980 XtNfromHoriz, current->form2a4,
981 XtNfromVert, current->form2a_label_permissions,
982 XtNborderWidth, 0,
983 NULL ) ;
984
985 /** Widgets for Form 2a5 **/
986
987 current->form2a5_label_blank =
988 XtVaCreateManagedWidget(
989 "form2a5_label_blank",
990 labelWidgetClass,
991 current->form2a5,
992 XtNlabel," ", /* Empty label to hold space in form */
993 XtNborderWidth, 0,
994 NULL ) ;
995
996 current->form2a5_label_setuid =
997 XtVaCreateManagedWidget(
998 "form2a5_label_setuid",
999 labelWidgetClass,
1000 current->form2a5,
1001 XtNlabel, "SetUID",
1002 XtNfromVert, current->form2a5_label_blank,
1003 XtNborderWidth, 0,
1004 NULL ) ;
1005
1006 current->form2a5_label_setgid =
1007 XtVaCreateManagedWidget(
1008 "form2a5_label_setgid",
1009 labelWidgetClass,
1010 current->form2a5,
1011 XtNlabel, "SetGID",
1012 XtNfromVert, current->form2a5_label_setuid,
1013 XtNborderWidth, 0,
1014 NULL );
1015
1016 current->form2a5_label_sticky =
1017 XtVaCreateManagedWidget(
1018 "form2a5_label_sticky",
1019 labelWidgetClass,
1020 current->form2a5,
1021 XtNlabel, "Sticky",
1022 XtNfromVert, current->form2a5_label_setgid,
1023 XtNborderWidth, 0,
1024 NULL );
1025
1026 /* Form 2a6 */
1027
1028 current->form2a6 =
1029 XtVaCreateManagedWidget(
1030 "form2a6",
1031 xedwFormWidgetClass,
1032 current->form2a,
1033 XtNfromHoriz, current->form2a5,
1034 XtNfromVert, current->form2a_label_permissions,
1035 XtNborderWidth, 0,
1036 NULL ) ;
1037
1038 /** Widgets for Form 2a6 **/
1039
1040 current->form2a6_label_blank =
1041 XtVaCreateManagedWidget(
1042 "form2a6_label_blank",
1043 labelWidgetClass,
1044 current->form2a6,
1045 XtNlabel," ", /* Empty label to hold space in form */
1046 XtNborderWidth, 0,
1047 NULL ) ;
1048
1049 current->form2a6_button_setuid =
1050 XtVaCreateManagedWidget(
1051 "form2a6_button_setuid",
1052 commandWidgetClass,
1053 current->form2a6,
1054 XtNfromVert, current->form2a6_label_blank,
1055 NULL ) ;
1056
1057 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1058 infobutton->fileinfo = current;
1059 infobutton->select = uid_but;
1060 XtAddCallback(current->form2a6_button_setuid, XtNcallback,
1061 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
1062 XtAddCallback(current->form2a6_button_setuid, XtNdestroyCallback,
1063 (XtCallbackProc)free_info, (XtPointer)infobutton);
1064
1065 current->form2a6_button_setgid =
1066 XtVaCreateManagedWidget(
1067 "form2a6_button_setgid",
1068 commandWidgetClass,
1069 current->form2a6,
1070 XtNfromVert, current->form2a6_button_setuid,
1071 NULL ) ;
1072
1073 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1074 infobutton->fileinfo = current;
1075 infobutton->select = gid_but;
1076 XtAddCallback(current->form2a6_button_setgid, XtNcallback,
1077 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
1078 XtAddCallback(current->form2a6_button_setgid, XtNdestroyCallback,
1079 (XtCallbackProc)free_info, (XtPointer)infobutton);
1080
1081 current->form2a6_button_sticky =
1082 XtVaCreateManagedWidget(
1083 "form2a6_button_sticky",
1084 commandWidgetClass,
1085 current->form2a6,
1086 XtNfromVert, current->form2a6_button_setgid,
1087 NULL ) ;
1088
1089 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1090 infobutton->fileinfo = current;
1091 infobutton->select = stky_but;
1092 XtAddCallback(current->form2a6_button_sticky, XtNcallback,
1093 (XtCallbackProc)dcbutton_toggled, (XtPointer)infobutton);
1094 XtAddCallback(current->form2a6_button_sticky, XtNdestroyCallback,
1095 (XtCallbackProc)free_info, (XtPointer)infobutton);
1096
1097 /* Form 2b */
1098
1099 current->form2b =
1100 XtVaCreateManagedWidget(
1101 "form2b",
1102 xedwFormWidgetClass,
1103 current->form2,
1104 XtNfullHeight, True,
1105 XtNfromHoriz, current->form2a,
1106 XtNborderWidth, 0,
1107 XtNheightLinked, current->form2a6,
1108 NULL ) ;
1109
1110 /** Widgets for Form 2b **/
1111
1112 current->form2b_command_update =
1113 XtVaCreateManagedWidget(
1114 "form2b_command_update",
1115 commandWidgetClass,
1116 current->form2b,
1117 XtNlabel, "Update",
1118 XtNfullWidth, True,
1119 NULL ) ;
1120
1121 XtAddCallback(current->form2b_command_update, XtNcallback,
1122 (XtCallbackProc)update_func, (XtPointer)current);
1123
1124 current->form2b_command_undo =
1125 XtVaCreateManagedWidget(
1126 "form2b_command_undo",
1127 commandWidgetClass,
1128 current->form2b,
1129 XtNlabel, "Undo",
1130 XtNfromVert, current->form2b_command_update,
1131 XtNfullWidth, True,
1132 NULL ) ;
1133
1134 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1135 infobutton->fileinfo = current;
1136 infobutton->mode = UNDO;
1137 XtAddCallback(current->form2b_command_undo, XtNcallback,
1138 (XtCallbackProc)undo_func, (XtPointer)infobutton);
1139 XtAddCallback(current->form2b_command_undo, XtNdestroyCallback,
1140 (XtCallbackProc)free_info, (XtPointer)infobutton);
1141
1142 current->form2b_command_reset =
1143 XtVaCreateManagedWidget(
1144 "form2b_command_reset",
1145 commandWidgetClass,
1146 current->form2b,
1147 XtNlabel, "Reset",
1148 XtNfromVert, current->form2b_command_undo,
1149 XtNfullWidth, True,
1150 NULL ) ;
1151
1152 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1153 infobutton->fileinfo = current;
1154 infobutton->mode = RESET;
1155 XtAddCallback(current->form2b_command_reset, XtNcallback,
1156 (XtCallbackProc)undo_func, (XtPointer)infobutton);
1157 XtAddCallback(current->form2b_command_reset, XtNdestroyCallback,
1158 (XtCallbackProc)free_info, (XtPointer)infobutton);
1159
1160 /* Form 3 */
1161
1162 current->form3 =
1163 XtVaCreateManagedWidget(
1164 "form3",
1165 xedwFormWidgetClass,
1166 current->form,
1167 XtNfullWidth, True,
1168 XtNborderWidth, 1,
1169 XtNfromVert, current->form2,
1170 NULL ) ;
1171
1172 /** Widgets for Form 3 **/
1173
1174 current->form3_command_done =
1175 XtVaCreateManagedWidget(
1176 "form3_command_done",
1177 commandWidgetClass,
1178 current->form3,
1179 XtNlabel, "DONE",
1180 NULL ) ;
1181
1182 XtAddCallback(current->form3_command_done, XtNcallback,
1183 (XtCallbackProc)destroy_doubleclick_dialog,
1184 (XtPointer)current);
1185
1186 current->form3_command_view =
1187 XtVaCreateManagedWidget(
1188 "form3_command_view",
1189 commandWidgetClass,
1190 current->form3,
1191 XtNlabel, " View ",
1192 XtNfromHoriz, current->form3_command_done,
1193 NULL ) ;
1194
1195 XtAddCallback(current->form3_command_view, XtNcallback,
1196 (XtCallbackProc)view_func, (XtPointer)current);
1197
1198 current->form3_command_edit =
1199 XtVaCreateManagedWidget(
1200 "form3_command_edit",
1201 commandWidgetClass,
1202 current->form3,
1203 XtNlabel, " Edit ",
1204 XtNfromHoriz, current->form3_command_view,
1205 NULL ) ;
1206
1207 XtAddCallback(current->form3_command_edit, XtNcallback,
1208 (XtCallbackProc)view_func, (XtPointer)current);
1209
1210 current->form3_command_execwin =
1211 XtVaCreateManagedWidget(
1212 "form3_command_execwin",
1213 commandWidgetClass,
1214 current->form3,
1215 XtNlabel, "Execute in Window",
1216 XtNfromHoriz, current->form3_command_edit,
1217 NULL ) ;
1218
1219 XtAddCallback(current->form3_command_execwin, XtNcallback,
1220 (XtCallbackProc)execwin_func, (XtPointer)current);
1221
1222 current->form3_command_execback =
1223 XtVaCreateManagedWidget(
1224 "form3_command_execback",
1225 commandWidgetClass,
1226 current->form3,
1227 XtNlabel, "Execute in Background",
1228 XtNfromHoriz, current->form3_command_execwin,
1229 NULL ) ;
1230
1231 XtAddCallback(current->form3_command_execback, XtNcallback,
1232 (XtCallbackProc)execback_realize, (XtPointer)current);
1233
1234 current->form3_command_help =
1235 XtVaCreateManagedWidget(
1236 "form3_command_help",
1237 commandWidgetClass,
1238 current->form3,
1239 XtNlabel, "Help",
1240 XtNfromHoriz, current->form3_command_execback,
1241 NULL ) ;
1242
1243 XtAddCallback(current->form3_command_help, XtNcallback,
1244 (XtCallbackProc)help_func, (XtPointer)current);
1245
1246 /* Execute in background popup initialization */
1247
1248 current->eb_popup =
1249 XtVaCreatePopupShell(
1250 "eb_popup",
1251 transientShellWidgetClass,
1252 current->fileInfoDialog,
1253 NULL ) ;
1254
1255 current->ebform =
1256 XtVaCreateManagedWidget(
1257 "ebform",
1258 xedwFormWidgetClass,
1259 current->eb_popup,
1260 XtNborderWidth, 1,
1261 NULL ) ;
1262
1263 current->eblabeltitle =
1264 XtVaCreateManagedWidget(
1265 "eblabeltitle",
1266 labelWidgetClass,
1267 current->ebform,
1268 XtNlabel, "Execute in Background",
1269 XtNjustify, XtJustifyCenter,
1270 XtNborderWidth, 1,
1271 XtNfullWidth, True,
1272 NULL ) ;
1273
1274 current->eblabelsubtitle =
1275 XtVaCreateManagedWidget(
1276 "eblabelsubtitle",
1277 labelWidgetClass,
1278 current->ebform,
1279 XtNlabel, "Set I/O Redirection",
1280 XtNfromVert, current->eblabeltitle,
1281 XtNjustify, XtJustifyCenter,
1282 XtNborderWidth, 0,
1283 XtNfullWidth, True,
1284 NULL ) ;
1285
1286 current->ebform1 =
1287 XtVaCreateManagedWidget(
1288 "ebform1",
1289 xedwFormWidgetClass,
1290 current->ebform,
1291 XtNborderWidth, 0,
1292 XtNfromVert, current->eblabelsubtitle,
1293 NULL ) ;
1294
1295 current->ebform2 =
1296 XtVaCreateManagedWidget(
1297 "ebform2",
1298 xedwFormWidgetClass,
1299 current->ebform,
1300 XtNborderWidth, 0,
1301 XtNfromHoriz, current->ebform1,
1302 XtNfromVert, current->eblabelsubtitle,
1303 XtNheightLinked, current->ebform1,
1304 NULL ) ;
1305
1306 current->eblabelinput =
1307 XtVaCreateManagedWidget(
1308 "eblabelinput",
1309 labelWidgetClass,
1310 current->ebform1,
1311 XtNlabel, "Input:",
1312 XtNborderWidth, 0,
1313 XtNjustify, XtJustifyRight,
1314 XtNfullWidth, True,
1315 NULL ) ;
1316
1317 strcpy(current->eb_input, "/dev/null");
1318 strcpy(current->eb_output, current->eb_input);
1319 strcpy(current->eb_error, current->eb_input);
1320
1321 current->ebtextinput =
1322 XtVaCreateManagedWidget(
1323 "ebtextinput",
1324 asciiTextWidgetClass,
1325 current->ebform2,
1326 XtNstring, current->eb_input,
1327 XtNeditType, XawtextEdit,
1328 XtNlength, 255,
1329 XtNuseStringInPlace, True,
1330 NULL ) ;
1331
1332 XtOverrideTranslations(current->ebtextinput, textWidgettranslations);
1333
1334 current->eblabeloutput =
1335 XtVaCreateManagedWidget(
1336 "eblabeloutput",
1337 labelWidgetClass,
1338 current->ebform1,
1339 XtNlabel, "Output:",
1340 XtNfromVert, current->eblabelinput,
1341 XtNfullWidth, True,
1342 XtNjustify, XtJustifyRight,
1343 XtNborderWidth, 0,
1344 NULL ) ;
1345
1346 current->ebtextoutput =
1347 XtVaCreateManagedWidget(
1348 "ebtextoutput",
1349 asciiTextWidgetClass,
1350 current->ebform2,
1351 XtNstring, current->eb_output,
1352 XtNeditType, XawtextEdit,
1353 XtNfromVert, current->ebtextinput,
1354 XtNlength, 255,
1355 XtNuseStringInPlace, True,
1356 NULL ) ;
1357
1358 XtOverrideTranslations(current->ebtextoutput, textWidgettranslations);
1359
1360 current->eblabelerror =
1361 XtVaCreateManagedWidget(
1362 "eblabelerror",
1363 labelWidgetClass,
1364 current->ebform1,
1365 XtNlabel, "Error:",
1366 XtNfromVert, current->eblabeloutput,
1367 XtNfullWidth, True,
1368 XtNjustify, XtJustifyRight,
1369 XtNborderWidth, 0,
1370 NULL ) ;
1371
1372 current->ebtexterror =
1373 XtVaCreateManagedWidget(
1374 "ebtexterror",
1375 asciiTextWidgetClass,
1376 current->ebform2,
1377 XtNfromVert, current->ebtextoutput,
1378 XtNstring, current->eb_error,
1379 XtNeditType, XawtextEdit,
1380 XtNlength, 255,
1381 XtNuseStringInPlace, True,
1382 NULL ) ;
1383
1384 XtOverrideTranslations(current->ebtexterror, textWidgettranslations);
1385
1386 current->ebcommandok =
1387 XtVaCreateManagedWidget(
1388 "ebcommandok",
1389 commandWidgetClass,
1390 current->ebform,
1391 XtNfromVert, current->ebform2,
1392 XtNlabel, "OK",
1393 NULL ) ;
1394
1395 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1396 infobutton->fileinfo = current;
1397 infobutton->select = 1;
1398 XtAddCallback(current->ebcommandok, XtNcallback,
1399 (XtCallbackProc)execback_popdown, (XtPointer)infobutton);
1400 XtAddCallback(current->ebcommandok, XtNdestroyCallback,
1401 (XtCallbackProc)free_info, (XtPointer)infobutton);
1402
1403 current->ebcommandcancel =
1404 XtVaCreateManagedWidget(
1405 "ebcommandcancel",
1406 commandWidgetClass,
1407 current->ebform,
1408 XtNfromVert, current->ebform1,
1409 XtNfromHoriz, current->ebcommandok,
1410 XtNlabel, "Cancel",
1411 NULL ) ;
1412
1413 infobutton = (InfoButtons*) XtMalloc(sizeof(InfoButtons));
1414 infobutton->fileinfo = current;
1415 infobutton->select = 0;
1416 XtAddCallback(current->ebcommandcancel, XtNcallback,
1417 (XtCallbackProc)execback_popdown, (XtPointer)infobutton);
1418 XtAddCallback(current->ebcommandcancel, XtNdestroyCallback,
1419 (XtCallbackProc)free_info, (XtPointer)infobutton);
1420
1421 /* Verify Quit PopUp */
1422
1423 current->verify_popup =
1424 XtVaCreatePopupShell(
1425 "Verify Done",
1426 transientShellWidgetClass,
1427 current->fileInfoDialog,
1428 NULL ) ;
1429
1430 current->verify_form =
1431 XtVaCreateManagedWidget(
1432 "verify_form",
1433 xedwFormWidgetClass,
1434 current->verify_popup,
1435 XtNborderWidth, 1,
1436 NULL ) ;
1437
1438 current->verify_label =
1439 XtVaCreateManagedWidget(
1440 "verify_label",
1441 labelWidgetClass,
1442 current->verify_form,
1443 XtNlabel, "Save changes?",
1444 XtNborderWidth, 0,
1445 NULL ) ;
1446
1447 current->verify_yes =
1448 XtVaCreateManagedWidget(
1449 "verify_yes",
1450 commandWidgetClass,
1451 current->verify_form,
1452 XtNlabel, "Yes",
1453 XtNborderWidth, 1,
1454 XtNfromVert, current->verify_label,
1455 NULL ) ;
1456
1457 XtAddCallback(current->verify_yes, XtNcallback,
1458 (XtCallbackProc)verify_callback, (XtPointer)current);
1459
1460 current->verify_no =
1461 XtVaCreateManagedWidget(
1462 "verify_no",
1463 commandWidgetClass,
1464 current->verify_form,
1465 XtNlabel, "No",
1466 XtNborderWidth, 1,
1467 XtNfromVert, current->verify_label,
1468 XtNfromHoriz, current->verify_yes,
1469 NULL ) ;
1470
1471 XtAddCallback(current->verify_no, XtNcallback,
1472 (XtCallbackProc)verify_callback, (XtPointer)current);
1473
1474 current->verify_cancel =
1475 XtVaCreateManagedWidget(
1476 "verify_cancel",
1477 commandWidgetClass,
1478 current->verify_form,
1479 XtNlabel, "Cancel",
1480 XtNborderWidth, 1,
1481 XtNfromVert, current->verify_label,
1482 XtNfromHoriz, current->verify_no,
1483 NULL ) ;
1484
1485 XtAddCallback(current->verify_cancel, XtNcallback,
1486 (XtCallbackProc)verify_callback, (XtPointer)current);
1487
1488 current->button[rown].bitmask = IREAD;
1489 current->button[rown].widget = current->form2a2_button_rown;
1490 current->button[rown].state = FALSE;
1491 current->button[rgrp].bitmask = GREAD;
1492 current->button[rgrp].widget = current->form2a2_button_rgrp;
1493 current->button[rgrp].state = FALSE;
1494 current->button[roth].bitmask = AREAD;
1495 current->button[roth].widget = current->form2a2_button_roth;
1496 current->button[roth].state = FALSE;
1497 current->button[wown].bitmask = IWRITE;
1498 current->button[wown].widget = current->form2a3_button_wown;
1499 current->button[wown].state = FALSE;
1500 current->button[wgrp].bitmask = GWRITE;
1501 current->button[wgrp].widget = current->form2a3_button_wgrp;
1502 current->button[wgrp].state = FALSE;
1503 current->button[woth].bitmask = AWRITE;
1504 current->button[woth].widget = current->form2a3_button_woth;
1505 current->button[woth].state = FALSE;
1506 current->button[xown].bitmask = IEXEC;
1507 current->button[xown].widget = current->form2a4_button_xown;
1508 current->button[xown].state = FALSE;
1509 current->button[xgrp].bitmask = GEXEC;
1510 current->button[xgrp].widget = current->form2a4_button_xgrp;
1511 current->button[xgrp].state = FALSE;
1512 current->button[xoth].bitmask = AEXEC;
1513 current->button[xoth].widget = current->form2a4_button_xoth;
1514 current->button[xoth].state = FALSE;
1515 current->button[uid_but].bitmask = S_ISUID;
1516 current->button[uid_but].widget = current->form2a6_button_setuid;
1517 current->button[uid_but].state = FALSE;
1518 current->button[gid_but].bitmask = S_ISGID;
1519 current->button[gid_but].widget = current->form2a6_button_setgid;
1520 current->button[gid_but].state = FALSE;
1521 current->button[stky_but].bitmask = S_ISVTX;
1522 current->button[stky_but].widget = current->form2a6_button_sticky;
1523 current->button[stky_but].state = FALSE;
1524
1525 /* Initialize applist */
1526
1527 current->applist = NULL;
1528
1529 return(current);
1530 }
1531
1532 /*****************************************************************************
1533 * WM_destroy_doubleclick_dialog *
1534 *****************************************************************************/
1535 #if NeedFunctionPrototypes
WM_destroy_doubleclick_dialog(Widget w,Fileinfo * current,XEvent * event,Boolean * dispatch)1536 private void WM_destroy_doubleclick_dialog(Widget w,
1537 Fileinfo *current,
1538 XEvent *event,
1539 Boolean *dispatch)
1540 #else
1541 private void WM_destroy_doubleclick_dialog(w, current, event, dispatch)
1542 Widget w;
1543 Fileinfo *current;
1544 XEvent *event;
1545 Boolean *dispatch;
1546 #endif
1547 {
1548 extern Atom protocols[2]; /* defined in dialogs.c */
1549
1550 if ((event->xclient.message_type == protocols[1]) &&
1551 (event->xclient.data.l[0] == protocols[0]))
1552 /* the widget got a kill signal */
1553 {
1554 /* Directly call callback of Done button */
1555 destroy_doubleclick_dialog(current->form3_command_done, current, NULL);
1556 }
1557 }
1558
1559 /*****************************************************************************
1560 * doubleclick_dialog *
1561 *****************************************************************************/
doubleclick_dialog(filename,path)1562 public void doubleclick_dialog(filename, path)
1563 String filename, path;
1564 {
1565 Fileinfo *current;
1566
1567 current = create_doubleclick();
1568
1569 strcpy(current->dc_filename, filename);
1570 strcpy(current->dc_path, path);
1571 if (strcmp(current->dc_path, "/") != 0)
1572 strcat(current->dc_path, "/");
1573
1574 strcpy(current->dc_fullname,current->dc_path);
1575 strcat(current->dc_fullname,filename);
1576
1577 strcpy(current->edit_filename, filename);
1578
1579 /* Load filename widget */
1580
1581 XtVaSetValues(
1582 current->form1a_text_filename,
1583 XtNstring, current->edit_filename,
1584 NULL ) ;
1585
1586 /* Stat our file for permission and owner/group information */
1587
1588 if (stat(current->dc_fullname, &(current->filestat)) == -1) {
1589 fprintf(stderr, "File status unreadable!\n");
1590 } else {
1591 struct passwd *pw;
1592 struct group *grp;
1593
1594
1595 /* Save the initial stat information for undo */
1596
1597 current->oldstat.mode = current->laststat.mode = current->filestat.st_mode;
1598
1599 /* Load the name of the owner of the file into the owner text widget */
1600 if ((pw = (struct passwd*)getpwuid(current->filestat.st_uid)) != NULL)
1601 strcpy(current->edit_owner, pw->pw_name);
1602 else sprintf(current->edit_owner, "%d",
1603 (short)current->filestat.st_uid);
1604
1605
1606 XtVaSetValues(
1607 current->form1c_text_owner,
1608 XtNstring, current->edit_owner,
1609 NULL ) ;
1610
1611 /* Load the name of the group of the file into the group text widget */
1612 if ((grp = (struct group*)getgrgid(current->filestat.st_gid)) != NULL)
1613 strcpy(current->edit_group, grp->gr_name);
1614 else sprintf(current->edit_group, "%d",
1615 (short)current->filestat.st_gid);
1616
1617
1618 XtVaSetValues(
1619 current->form1c_text_group,
1620 XtNstring, current->edit_group,
1621 NULL ) ;
1622
1623 /* Save filename, owner and group into last_* and old_* buffers for
1624 posterity. */
1625
1626 strcpy(current->oldstat.filename, current->edit_filename);
1627 strcpy(current->oldstat.owner, current->edit_owner);
1628 strcpy(current->oldstat.group, current->edit_group);
1629
1630 strcpy(current->laststat.filename, current->edit_filename);
1631 strcpy(current->laststat.owner, current->edit_owner);
1632 strcpy(current->laststat.group, current->edit_group);
1633
1634 /* Load the proper icon for the icon_label */
1635
1636 set_icon(current);
1637
1638 /* Load the file modification date and size */
1639
1640 set_size_date(current);
1641
1642 /* Set the buttons and command widgets */
1643
1644 update_buttons(INIT, current);
1645
1646 /* Put the dialog on screen */
1647
1648 XtRealizeWidget(current->fileInfoDialog);
1649
1650 XawTextSetInsertionPoint(current->form1a_text_filename,
1651 strlen(current->edit_filename));
1652 XawTextSetInsertionPoint(current->form1c_text_owner,
1653 strlen(current->edit_owner));
1654 XawTextSetInsertionPoint(current->form1c_text_group,
1655 strlen(current->edit_group));
1656
1657 realize_dialog(current->fileInfoDialog, NULL, XtGrabNone,
1658 (XtEventHandler)WM_destroy_doubleclick_dialog, current);
1659
1660 } /* end of if (stat(dc_fullname, &filestat) == -1) */
1661 }
1662
1663 /*****************************************************************************
1664 * update_buttons *
1665 *****************************************************************************/
update_buttons(mode,current)1666 private void update_buttons(mode, current)
1667 int mode;
1668 Fileinfo *current;
1669 {
1670 static uid_t uid, euid; /* user and effective user id's for program */
1671 Cardinal i;
1672 struct stat dirstat;
1673
1674 #define CHANGED(b) (current->button[b].state != (current->button[b].bitmask & current->filestat.st_mode))
1675 #define USEREXEC (current->filestat.st_mode & IEXEC)
1676 #define USERREAD (current->filestat.st_mode & IREAD)
1677 #define USERWRITE (current->filestat.st_mode & IWRITE)
1678 #define GROUPEXEC (current->filestat.st_mode & GEXEC)
1679 #define GROUPREAD (current->filestat.st_mode & GREAD)
1680 #define GROUPWRITE (current->filestat.st_mode & GWRITE)
1681 #define OTHEREXEC (current->filestat.st_mode & AEXEC)
1682 #define OTHERREAD (current->filestat.st_mode & AREAD)
1683 #define OTHERWRITE (current->filestat.st_mode & AWRITE)
1684 #define ANYEXEC (current->filestat.st_mode & (IEXEC | GEXEC | AEXEC))
1685 #define REGULAR ((current->filestat.st_mode & S_IFMT) == S_IFREG)
1686 #define SYMLINK ((current->filestat.st_mode & S_IFMT) == S_IFLNK)
1687 #define DIRECTORY ((current->filestat.st_mode & S_IFMT) == S_IFDIR)
1688
1689 #define D_USERWRITE (dirstat.st_mode & IWRITE)
1690 #define D_GROUPWRITE (dirstat.st_mode & GWRITE)
1691 #define D_OTHERWRITE (dirstat.st_mode & AWRITE)
1692 #define D_STICKY (dirstat.st_mode & S_ISVTX)
1693
1694 /* Force all buttons to be initialized. */
1695
1696 if (mode == INIT) for (i= FIRSTBUTTON; i <= LASTBUTTON; i++)
1697 current->button[i].state = -1;
1698
1699 if (mode == INIT || mode == UNDO) {
1700 if CHANGED(rown) SetButton(rown);
1701 if CHANGED(rgrp) SetButton(rgrp);
1702 if CHANGED(roth) SetButton(roth);
1703 if CHANGED(wown) SetButton(wown);
1704 if CHANGED(wgrp) SetButton(wgrp);
1705 if CHANGED(woth) SetButton(woth);
1706 if CHANGED(xown) SetButton(xown);
1707 if CHANGED(xgrp) SetButton(xgrp);
1708 if CHANGED(xoth) SetButton(xoth);
1709 if CHANGED(uid_but) SetButton(uid_but);
1710 if CHANGED(gid_but) SetButton(gid_but);
1711 if CHANGED(stky_but) SetButton(stky_but);
1712 }
1713
1714 if (mode == INIT) {
1715
1716 if (stat(current->dc_path, &dirstat) == -1) {
1717 fprintf(stderr, "Can't stat %s.\n", current->dc_path);
1718 }
1719
1720 /* Set up the default button sensitivity */
1721
1722 uid = getuid();
1723 euid = geteuid();
1724
1725 XtVaSetValues(current->form2b_command_reset, XtNsensitive, False, NULL);
1726 XtVaSetValues(current->form2b_command_undo, XtNsensitive, False, NULL);
1727 XtVaSetValues(current->form2b_command_update, XtNsensitive, False, NULL);
1728
1729 /* Assume we can modify permissions until proven otherwise.
1730 Note that we only do this at INIT, as we are assuming
1731 that the user can't change his any of his identities
1732 during his usage of this dialog box. So the section
1733 that handles root user access won't set any of these to
1734 true, since it assumes that they couldn't have been
1735 set to false, since the user must have always been
1736 root. */
1737
1738 XtVaSetValues(current->form2a2_button_rown, XtNsensitive, True, NULL);
1739 XtVaSetValues(current->form2a2_button_rgrp, XtNsensitive, True, NULL);
1740 XtVaSetValues(current->form2a2_button_roth, XtNsensitive, True, NULL);
1741 XtVaSetValues(current->form2a3_button_wown, XtNsensitive, True, NULL);
1742 XtVaSetValues(current->form2a3_button_wgrp, XtNsensitive, True, NULL);
1743 XtVaSetValues(current->form2a3_button_woth, XtNsensitive, True, NULL);
1744 XtVaSetValues(current->form2a4_button_xown, XtNsensitive, True, NULL);
1745 XtVaSetValues(current->form2a4_button_xgrp, XtNsensitive, True, NULL);
1746 XtVaSetValues(current->form2a4_button_xoth, XtNsensitive, True, NULL);
1747 XtVaSetValues(current->form2a6_button_setuid, XtNsensitive, True, NULL);
1748 XtVaSetValues(current->form2a6_button_setgid, XtNsensitive, True, NULL);
1749 XtVaSetValues(current->form2a6_button_sticky, XtNsensitive, True, NULL);
1750 XtVaSetValues(current->form1a_text_filename, XtNsensitive, True, NULL);
1751 XtVaSetValues(current->form1c_text_owner, XtNsensitive, True, NULL);
1752 XtVaSetValues(current->form1c_text_group, XtNsensitive, True, NULL);
1753 XawTextDisplayCaret(current->form1a_text_filename, True);
1754 XawTextDisplayCaret(current->form1c_text_owner, True);
1755 XawTextDisplayCaret(current->form1c_text_group, True);
1756 }
1757
1758 if (!uid || !euid) /* We're root */
1759 {
1760 if (ANYEXEC && (REGULAR || SYMLINK))
1761 {
1762 if (mode == UPDATE || mode == UNDO || mode == INIT)
1763 {
1764 XtVaSetValues(current->form3_command_execwin,
1765 XtNsensitive, True, NULL);
1766 XtVaSetValues(current->form3_command_execback,
1767 XtNsensitive, True, NULL);
1768 }
1769 XtVaSetValues(current->form2a6_button_sticky,
1770 XtNsensitive, True, NULL);
1771 }
1772 else
1773 {
1774 if (mode == UPDATE || mode == UNDO || mode == INIT)
1775 {
1776 XtVaSetValues(current->form3_command_execwin,
1777 XtNsensitive, False, NULL);
1778 XtVaSetValues(current->form3_command_execback,
1779 XtNsensitive, False, NULL);
1780 }
1781 if (!DIRECTORY)
1782 {
1783 XtVaSetValues(current->form2a6_button_sticky,
1784 XtNsensitive, False, NULL);
1785 current->filestat.st_mode &= ~S_ISVTX;
1786 SetButton(stky_but);
1787 }
1788 }
1789
1790 /* The setgid and setuid bits may only be on if the corresponding execute
1791 bit is on. We check those bits here, even though they don't affect the
1792 root user's ability to do anything else. */
1793
1794 if (USEREXEC && (REGULAR || SYMLINK))
1795 {
1796 XtSetSensitive(current->form2a6_button_setuid, True);
1797 }
1798 else
1799 {
1800 current->filestat.st_mode &= ~S_ISUID;
1801 SetButton(uid_but);
1802 XtSetSensitive(current->form2a6_button_setuid, False);
1803 }
1804
1805 if (GROUPEXEC && (REGULAR || SYMLINK))
1806 {
1807 XtSetSensitive(current->form2a6_button_setgid, True);
1808 }
1809 else
1810 {
1811 current->filestat.st_mode &= ~S_ISGID;
1812 SetButton(gid_but);
1813 XtSetSensitive(current->form2a6_button_setgid, False);
1814 }
1815
1816 if (DIRECTORY)
1817 {
1818 XtSetSensitive(current->form3_command_view, False);
1819 XtSetSensitive(current->form3_command_edit, False);
1820 XtSetSensitive(current->form2a6_button_sticky, True);
1821 }
1822 else
1823 {
1824 XtSetSensitive(current->form3_command_view, True);
1825 XtSetSensitive(current->form3_command_edit, True);
1826 }
1827
1828 /* If we can view the file, (the file is not a directory)
1829 We can edit the file regardless of permission bits */
1830
1831 current->file_editable = TRUE;
1832 }
1833 else /* Oops, we're not root */
1834 {
1835 if (mode == INIT)
1836 {
1837 /* If we don't have write permission in this directory,
1838 we can't rename the file. */
1839
1840 if ((uid == dirstat.st_uid) || (euid == dirstat.st_uid))
1841 {
1842 if (!D_USERWRITE)
1843 {
1844 XtSetSensitive(current->form1a_text_filename, False);
1845 XawTextDisplayCaret(current->form1a_text_filename, False);
1846 }
1847 }
1848 else if (user_is_member(dirstat.st_gid))
1849 {
1850 if (!D_GROUPWRITE || D_STICKY)
1851 {
1852 XtSetSensitive(current->form1a_text_filename, False);
1853 XawTextDisplayCaret(current->form1a_text_filename, False);
1854 }
1855 }
1856 else if (!D_OTHERWRITE || D_STICKY)
1857 {
1858 XtSetSensitive(current->form1a_text_filename, False);
1859 XawTextDisplayCaret(current->form1a_text_filename, False);
1860 }
1861
1862 /* Non-root, can't chown */
1863
1864 XtVaSetValues(
1865 current->form1c_text_owner,
1866 XtNsensitive, False,
1867 XtNeditType, XawtextRead,
1868 NULL ) ;
1869 XawTextDisplayCaret(current->form1c_text_owner, False);
1870
1871 if (!DIRECTORY)
1872 {
1873 current->filestat.st_mode &= ~S_ISVTX; /* Turn off sticky */
1874 SetButton(stky_but);
1875 XtSetSensitive(current->form2a6_button_sticky, False);
1876 }
1877 }
1878
1879 if ((uid == current->filestat.st_uid) ||
1880 (euid == current->filestat.st_uid))
1881 {
1882
1883 /* We are the owner of the file. Let's see how our permissions
1884 affect our possible commands, and turn off ones that do
1885 not apply with the current permissions. */
1886
1887 if (USEREXEC && (REGULAR || SYMLINK))
1888 {
1889 if (mode == UPDATE || mode == UNDO || mode == INIT)
1890 {
1891 XtVaSetValues(current->form3_command_execwin,
1892 XtNsensitive, True, NULL);
1893 XtVaSetValues(current->form3_command_execback,
1894 XtNsensitive, True, NULL);
1895 }
1896 XtVaSetValues(current->form2a6_button_setuid,
1897 XtNsensitive, True, NULL);
1898 }
1899 else
1900 {
1901 if (mode == UPDATE || mode == UNDO || mode == INIT)
1902 {
1903 XtVaSetValues(current->form3_command_execback,
1904 XtNsensitive, False, NULL);
1905 XtVaSetValues(current->form3_command_execwin,
1906 XtNsensitive, False, NULL);
1907 }
1908 current->filestat.st_mode &= ~S_ISUID; /* Turn off Setuid */
1909 SetButton(uid_but);
1910 XtVaSetValues(current->form2a6_button_setuid,
1911 XtNsensitive, False, NULL);
1912 }
1913 if (GROUPEXEC && (REGULAR || SYMLINK))
1914 {
1915 XtSetSensitive(current->form2a6_button_setgid, True);
1916 }
1917 else /* Group exec permission is off */
1918 {
1919 current->filestat.st_mode &= ~S_ISGID; /* Turn off Setgid */
1920 SetButton(gid_but);
1921 XtSetSensitive(current->form2a6_button_setgid, False);
1922 }
1923
1924 if (mode == UPDATE || mode == UNDO || mode == INIT)
1925 {
1926 if (USERREAD && (REGULAR || SYMLINK))
1927 {
1928 XtSetSensitive(current->form3_command_view, True);
1929 }
1930 else
1931 {
1932 XtSetSensitive(current->form3_command_view, False);
1933 XtSetSensitive(current->form3_command_edit, False);
1934 }
1935 if (!USERWRITE && (REGULAR || SYMLINK))
1936 {
1937 XtSetSensitive(current->form3_command_edit, False);
1938 current->file_editable = FALSE;
1939 }
1940 else if (USERREAD && (REGULAR || SYMLINK))
1941 {
1942 XtSetSensitive(current->form3_command_edit, True);
1943 current->file_editable = TRUE;
1944 }
1945 else
1946 XtSetSensitive(current->form3_command_edit, False);
1947 }
1948
1949 /* End of owner permission handling section */
1950
1951 } else /* not owner or root */ {
1952
1953 /* We're not root, and we don't own the file,
1954 so we can't change the permissions. */
1955
1956 if (mode == INIT)
1957 {
1958 /* Again, we do this only at INIT time, and we
1959 assume throughout this function that these values
1960 will remain unchanged for the duration of this
1961 dialog box. */
1962
1963 XtVaSetValues(current->form2a2_button_rown, XtNsensitive, False, NULL);
1964 XtVaSetValues(current->form2a2_button_rgrp, XtNsensitive, False, NULL);
1965 XtVaSetValues(current->form2a2_button_roth, XtNsensitive, False, NULL);
1966 XtVaSetValues(current->form2a3_button_wown, XtNsensitive, False, NULL);
1967 XtVaSetValues(current->form2a3_button_wgrp, XtNsensitive, False, NULL);
1968 XtVaSetValues(current->form2a3_button_woth, XtNsensitive, False, NULL);
1969 XtVaSetValues(current->form2a4_button_xown, XtNsensitive, False, NULL);
1970 XtVaSetValues(current->form2a4_button_xgrp, XtNsensitive, False, NULL);
1971 XtVaSetValues(current->form2a4_button_xoth, XtNsensitive, False, NULL);
1972 XtVaSetValues(current->form2a6_button_setuid, XtNsensitive, False,
1973 NULL);
1974 XtVaSetValues(current->form2a6_button_setgid, XtNsensitive, False,
1975 NULL);
1976 XtVaSetValues(current->form2a6_button_sticky, XtNsensitive, False,
1977 NULL);
1978 XtVaSetValues(current->form1c_text_group, XtNsensitive, False, NULL);
1979 XawTextDisplayCaret(current->form1c_text_group, False);
1980 }
1981
1982 /* Since we're not root and don't own the file,
1983 we don't have to worry about making changes to
1984 the setgid and setuid buttons in response to your
1985 run of the mill permission button clicks. So,
1986 all _group_ and _other_ permission handling will
1987 be done only if we are in UPDATE, UNDO, or INIT mode. */
1988
1989 if (mode == UPDATE || mode == UNDO || mode == INIT)
1990 {
1991 if (user_is_member(current->filestat.st_gid))
1992 {
1993 /* We're in the file's group */
1994
1995 if (GROUPEXEC && (REGULAR || SYMLINK))
1996 {
1997 XtSetSensitive(current->form3_command_execwin, True);
1998 XtSetSensitive(current->form3_command_execback, True);
1999 }
2000 else
2001 {
2002 XtSetSensitive(current->form3_command_execwin, False);
2003 XtSetSensitive(current->form3_command_execback, False);
2004 }
2005 if (GROUPREAD && (REGULAR || SYMLINK))
2006 {
2007 XtSetSensitive(current->form3_command_view, True);
2008 }
2009 else
2010 {
2011 XtSetSensitive(current->form3_command_view, False);
2012 XtSetSensitive(current->form3_command_edit, False);
2013 }
2014 if (!GROUPWRITE)
2015 {
2016 XtSetSensitive(current->form3_command_edit, False);
2017 current->file_editable = FALSE;
2018 }
2019 else if (GROUPREAD && (REGULAR || SYMLINK))
2020 {
2021 XtSetSensitive(current->form3_command_edit, True);
2022 current->file_editable = TRUE;
2023 }
2024
2025 /* End of group permission handling */
2026 }
2027 else
2028 {
2029 /* We're not owner or in group */
2030
2031 if (OTHEREXEC && (REGULAR || SYMLINK))
2032 {
2033 XtSetSensitive(current->form3_command_execwin, True);
2034 XtSetSensitive(current->form3_command_execback, True);
2035 }
2036 else
2037 {
2038 XtSetSensitive(current->form3_command_execwin, False);
2039 XtSetSensitive(current->form3_command_execback, False);
2040 }
2041 if (OTHERREAD && (REGULAR || SYMLINK))
2042 {
2043 XtSetSensitive(current->form3_command_view, True);
2044 }
2045 else
2046 {
2047 XtSetSensitive(current->form3_command_view, False);
2048 XtSetSensitive(current->form3_command_edit, False);
2049 }
2050
2051 if (!OTHERWRITE)
2052 {
2053 XtSetSensitive(current->form3_command_edit, False);
2054 current->file_editable = FALSE;
2055 }
2056 else if (OTHERREAD && (REGULAR || SYMLINK))
2057 {
2058 XtSetSensitive(current->form3_command_edit, True);
2059 current->file_editable = TRUE;
2060 }
2061
2062 /* End of other permissions handling */
2063 }
2064
2065 /* End of the UPDATE, UNDO, INIT test that surrounds
2066 all group and other permission handling */
2067 }
2068 /* End of non-root handling */
2069 }
2070 /* End of main body.. starting with if (!uid || !euid) */
2071 }
2072
2073 /* We don't want to allow folks to rename '.' or '..' */
2074
2075 if (!strcmp(".", current->dc_filename) ||
2076 !strcmp("..", current->dc_filename))
2077 {
2078 XawTextDisplayCaret(current->form1a_text_filename, False);
2079 XtSetSensitive(current->form1a_text_filename, False);
2080 }
2081 }
2082
2083 /*****************************************************************************
2084 * verify_callback *
2085 *****************************************************************************/
2086 /*ARGSUSED*/
verify_callback(w,current,call_data)2087 void verify_callback(w, current, call_data)
2088 Widget w;
2089 Fileinfo *current;
2090 XtPointer call_data;
2091 {
2092 extern Cursor left_ptr;
2093
2094 if (w == current->verify_cancel)
2095 XtPopdown(current->verify_popup);
2096 else
2097 {
2098 if (w == current->verify_yes)
2099 update_func(w, (XtPointer)current, 0);
2100
2101 XtPopdown(current->verify_popup);
2102 XtPopdown(current->fileInfoDialog);
2103
2104 if ((current->laststat.mode != current->oldstat.mode) ||
2105 (strcmp(current->laststat.filename, current->oldstat.filename)) ||
2106 (strcmp(current->laststat.owner, current->oldstat.owner)) ||
2107 (strcmp(current->laststat.group, current->oldstat.group)) ||
2108 (current->file_edited && (current_mode.mode != Icons)))
2109 {
2110 char path[255];
2111 int len = strlen(current->dc_path);
2112
2113 strcpy(path, current->dc_path);
2114
2115 if ((strcmp(path, "/") != 0) && (path[len-1] == '/'))
2116 path[len-1] = 0;
2117 directoryManagerNewDirectory(path);
2118 }
2119
2120 /* We can finally let the main interface go back to the non-busy cursor. */
2121
2122 setCursor(left_ptr);
2123 }
2124 }
2125
2126 /*****************************************************************************
2127 * destroy_doubleclick_dialog *
2128 *****************************************************************************/
2129 /*ARGSUSED*/
destroy_doubleclick_dialog(w,current,call_data)2130 void destroy_doubleclick_dialog(w, current, call_data)
2131 Widget w;
2132 Fileinfo *current;
2133 XtPointer call_data;
2134 {
2135 extern Cursor left_ptr;
2136
2137 /* Popdown the doubleclick dialog */
2138
2139 if ((current->filestat.st_mode != current->laststat.mode) ||
2140 (strcmp(current->edit_filename, current->laststat.filename)) ||
2141 (strcmp(current->edit_group, current->laststat.group)) ||
2142 (strcmp(current->edit_owner, current->laststat.owner))) {
2143 realize_dialog(current->verify_popup, NULL, XtGrabNonexclusive,
2144 NULL, NULL);
2145 } else {
2146 Fileinfoelement *c = Fileinfolist;
2147 Fileinfoelement *p;
2148
2149 XtPopdown(current->fileInfoDialog);
2150
2151 if ((current->laststat.mode != current->oldstat.mode) ||
2152 (strcmp(current->laststat.filename, current->oldstat.filename)) ||
2153 (strcmp(current->laststat.owner, current->oldstat.owner)) ||
2154 (strcmp(current->laststat.group, current->oldstat.group))
2155 )
2156 {
2157 char path[255];
2158 int len = strlen(current->dc_path);
2159
2160 strcpy(path, current->dc_path);
2161
2162 if ((strcmp(path, "/") != 0) && (path[len-1] == '/'))
2163 path[len-1] = 0;
2164 directoryManagerNewDirectory(path);
2165 }
2166
2167 setCursor(left_ptr);
2168
2169 /* Destroy all the widgets.. I could do this via just destroying the fileInfoDialog,
2170 * but I prefer to do it in a few seperate stages.
2171 */
2172 XtDestroyWidget(current->eb_popup);
2173 XtDestroyWidget(current->verify_popup);
2174 XtDestroyWidget(current->form1);
2175 XtDestroyWidget(current->form2);
2176 XtDestroyWidget(current->form3);
2177 XtDestroyWidget(current->fileInfoDialog);
2178
2179 /* delete all the memory associated with this instance of a double-click
2180 * then delete the Widgets them selves.
2181 */
2182 XtFree(current->filedate);
2183 XtFree(current->filesize);
2184 XtFree(current->edit_filename);
2185 XtFree(current->edit_owner);
2186 XtFree(current->edit_group);
2187 XtFree(current->dc_fullname);
2188 XtFree(current->dc_filename);
2189 XtFree(current->dc_path);
2190 XtFree(current->eb_input);
2191 XtFree(current->eb_output);
2192 XtFree(current->eb_error);
2193 XtFree((char *)current->xdtmlist_element);
2194
2195 /* Now we must delete this instance from our Fileinfolist, then free it */
2196 p = c;
2197 while (c != NULL && c->fileinfo != current) {
2198 /* This node is valid AND This node is NOT the current one.
2199 * Let's try the next node.
2200 */
2201 p = c; /* A pointer to the predecessor */
2202 c = c->next;
2203 }
2204 if (c == NULL) {
2205 /* We did NOT find the node in the list.. Mmmm VERY strange, in fact
2206 * stange enough for me to print a cryptic error message.
2207 */
2208 fprintf(stderr, "xdtm: Warning: permissions dialog not found in list when free'd\n");
2209 } else {
2210 /* OK we must have found it, let's take it out of the list. */
2211 if (Fileinfolist == c) {
2212 /* ah.. first element in the list.. OK.. if there are any more nodes
2213 * in the list then set the Fileinfolist to the second one.. if not
2214 * delete the whole bloody list.
2215 */
2216 if (c->next == NULL) {
2217 /* We are the only element in the list.. trash it!! */
2218 XtFree((char *)Fileinfolist);
2219 Fileinfolist = NULL;
2220 } else {
2221 /* There are more.. */
2222 Fileinfolist = c->next;
2223 XtFree((char *)c);
2224 }
2225 } else {
2226 /* We are in the middle of end of the list */
2227 p->next = c->next;
2228 XtFree((char *)c);
2229 }
2230 }
2231 /* We ALWAYS want to free the current node anyway */
2232 XtFree((char *)current);
2233 }
2234 }
2235
2236 /*****************************************************************************
2237 * free_info *
2238 *****************************************************************************/
2239 /*ARGSUSED*/
free_info(w,infobutton,call_data)2240 void free_info(w, infobutton, call_data)
2241 Widget w;
2242 InfoButtons *infobutton;
2243 XtPointer call_data;
2244 {
2245 XtFree((char *)infobutton);
2246 }
2247
2248 /*****************************************************************************
2249 * dcbutton_toggled *
2250 *****************************************************************************/
2251 /*ARGSUSED*/
dcbutton_toggled(w,infobutton,call_data)2252 void dcbutton_toggled(w, infobutton, call_data)
2253 Widget w;
2254 InfoButtons *infobutton;
2255 XtPointer call_data;
2256 {
2257 Buttons select;
2258 Fileinfo *current;
2259
2260 select = infobutton->select;
2261 current = infobutton->fileinfo;
2262 if (current->filestat.st_mode & current->button[select].bitmask) {
2263 current->filestat.st_mode &= ~current->button[select].bitmask;
2264 } else {
2265 current->filestat.st_mode |= current->button[select].bitmask;
2266 }
2267 SetButton(select);
2268
2269 /* If we've toggled the buttons around such that we are in
2270 the state we were in when we last wrote the permissions
2271 out, dim the update button to let the user know we
2272 are paying attention. */
2273
2274 if ((current->filestat.st_mode == current->laststat.mode) &&
2275 (!strcmp(current->edit_filename, current->laststat.filename)) &&
2276 (!strcmp(current->edit_owner, current->laststat.owner)) &&
2277 (!strcmp(current->edit_group, current->laststat.group))) {
2278 XtVaSetValues(current->form2b_command_update, XtNsensitive, False, NULL);
2279 XtVaSetValues(current->form2b_command_undo, XtNsensitive, False, NULL);
2280 } else {
2281 XtVaSetValues(current->form2b_command_update, XtNsensitive, True, NULL);
2282 XtVaSetValues(current->form2b_command_undo, XtNsensitive, True, NULL);
2283 }
2284
2285 if ((current->filestat.st_mode == current->oldstat.mode) &&
2286 (!strcmp(current->edit_filename, current->oldstat.filename)) &&
2287 (!strcmp(current->edit_owner, current->oldstat.owner)) &&
2288 (!strcmp(current->edit_group, current->oldstat.group))) {
2289 XtVaSetValues(current->form2b_command_reset, XtNsensitive, False, NULL);
2290 } else {
2291 XtVaSetValues(current->form2b_command_reset, XtNsensitive, True, NULL);
2292 }
2293
2294 update_buttons(TEMP, current);
2295 }
2296
2297 /*****************************************************************************
2298 * text_callback *
2299 *****************************************************************************/
2300 /*ARGSUSED*/
text_callback(w,current,call_data)2301 void text_callback(w, current, call_data)
2302 Widget w;
2303 Fileinfo *current;
2304 XtPointer call_data;
2305 {
2306
2307 XtSetSensitive(current->form2b_command_update, True);
2308 XtSetSensitive(current->form2b_command_undo, True);
2309 XtSetSensitive(current->form2b_command_reset, True);
2310
2311 if (w == current->form1c_text_group_src)
2312 {
2313 /* Turn off group set id if group name is changed. */
2314
2315 current->filestat.st_mode &= ~S_ISGID;
2316 SetButton(gid_but);
2317 }
2318 else if (w == current->form1c_text_owner_src)
2319 {
2320 /* Turn off user set id if group name is changed */
2321
2322 current->filestat.st_mode &= ~S_ISUID;
2323 SetButton(uid_but);
2324 }
2325 else if (w != current->form1a_text_filename_src)
2326 {
2327 fprintf(stderr, "Mystery text call-back!\n");
2328 }
2329 }
2330
2331 /*****************************************************************************
2332 * cancel_func *
2333 *****************************************************************************/
2334 /*ARGSUSED*/
cancel_func(w,client_data,call_data)2335 void cancel_func(w, client_data, call_data)
2336 Widget w;
2337 XtPointer client_data;
2338 XtPointer call_data;
2339 {
2340 }
2341
2342 /*****************************************************************************
2343 * view_func *
2344 *****************************************************************************/
2345 /*ARGSUSED*/
view_func(w,current,call_data)2346 void view_func(w, current, call_data)
2347 Widget w;
2348 Fileinfo *current;
2349 XtPointer call_data;
2350 {
2351 int localdescrip;
2352 #ifdef alliant
2353 int status;
2354 short magic_number;
2355 #endif
2356
2357 if (current->file_editable && (w == current->form3_command_edit)) {
2358 if ((localdescrip = open(current->dc_fullname, O_RDWR, 0644)) == -1)
2359 ioerr_dialog(errno);
2360 else {
2361
2362 /* Each processor has different magic numbers, therefore I won't
2363 * bother with trying to catch the editing of a binary file other
2364 * than for the alliant which I suppose must be Jon's machine.
2365 */
2366
2367 #ifdef alliant
2368 status = read(localdescrip, &magic_number, sizeof(short));
2369 if (status == -1) ioerr_dialog(errno);
2370 else if (magic_number == AVMAGIC) {
2371 alert_dialog("Can't edit a binary executable!", NULL, "Cancel");
2372 close(localdescrip);
2373 } else if (magic_number == ACMAGIC) {
2374 alert_dialog("Can't edit a binary object file!", NULL, "Cancel");
2375 close(localdescrip);
2376 } else if ((magic_number == OMAGIC) ||
2377 (magic_number == NMAGIC) ||
2378 (magic_number == ZMAGIC)) {
2379 alert_dialog("Can't edit binary load file!", NULL, "Cancel");
2380 close(localdescrip);
2381 } else {
2382
2383 #endif
2384 close(localdescrip);
2385 editfile(current->dc_fullname);
2386 current->file_edited = 1;
2387 #ifdef alliant
2388 }
2389 #endif
2390 }
2391 } else /* We are in non file_editable mode */ {
2392 if ((localdescrip = open(current->dc_fullname, O_RDONLY, 0644)) == -1)
2393 ioerr_dialog(errno);
2394 else /* We can open the file. */ {
2395
2396
2397 #ifdef alliant
2398 status = read(localdescrip, &magic_number, sizeof(short));
2399
2400 if (status == -1) ioerr_dialog(errno);
2401 else if (magic_number == AVMAGIC) {
2402 alert_dialog("Can't view a binary executable!", NULL, "Cancel");
2403 close(localdescrip);
2404 } else if (magic_number == ACMAGIC) {
2405 alert_dialog("Can't view a binary object file!", NULL, "Cancel");
2406 close(localdescrip);
2407 } else if ((magic_number == OMAGIC) ||
2408 (magic_number == NMAGIC) ||
2409 (magic_number == ZMAGIC)) {
2410 alert_dialog("Can't view binary load file!", NULL, "Cancel");
2411 close(localdescrip);
2412 } else {
2413
2414 #endif
2415 close(localdescrip);
2416 displayfile(current->dc_fullname, NULL, NULL, XtGrabNone);
2417 /* Close the double_click popup, otherwise no movement can occur in
2418 * the file being viewed.
2419 */
2420 /* destroy_doubleclick_dialog(NULL, NULL, NULL); */
2421 #ifdef alliant
2422 }
2423 #endif
2424 }
2425 }
2426 }
2427
2428 /*****************************************************************************
2429 * ioerr_dialog *
2430 *****************************************************************************/
ioerr_dialog(errnum)2431 public void ioerr_dialog(errnum)
2432 int errnum;
2433 {
2434 /* Yo Jon I like it.. Eddy. */
2435
2436 switch( errnum )
2437 {
2438 case ENOTDIR :
2439 /* FALL THROUGH */
2440
2441 case EINVAL :
2442 /* FALL THROUGH */
2443
2444 case ENAMETOOLONG :
2445 alert_dialog("Invalid filename error", NULL, NULL);
2446 break ;
2447
2448 case ENOENT :
2449 alert_dialog("Component of path or", "file does not exist", NULL);
2450 break ;
2451
2452 case EACCES :
2453 alert_dialog("Permission denied", NULL, NULL);
2454 break;
2455
2456 #ifndef TRUE_SYSV
2457 case ELOOP :
2458 alert_dialog("Symbolic link loop in path", NULL, NULL);
2459 break ;
2460 #endif
2461
2462 case EISDIR :
2463 alert_dialog("Tried to write to directory file", NULL, NULL);
2464 break;
2465
2466 case EROFS:
2467 alert_dialog("Can't write to file;", " File is on a read-only file system", NULL);
2468 break;
2469
2470 case EMFILE:
2471 alert_dialog("Too many open file descriptors", NULL, NULL);
2472 break;
2473
2474 case ENFILE:
2475 alert_dialog("System file table is full", NULL, NULL);
2476 break;
2477
2478 case ENXIO:
2479 alert_dialog("Device driver missing", NULL, NULL);
2480 break;
2481
2482 case ENOSPC:
2483 alert_dialog("No space to create file", NULL, NULL);
2484 break;
2485
2486 #ifdef EDQUOT
2487 case EDQUOT:
2488 alert_dialog("Quota over limit", NULL, NULL);
2489 break;
2490 #endif
2491
2492 case EIO:
2493 alert_dialog("I/O error while allocating inode", NULL, NULL);
2494 break;
2495
2496 case ETXTBSY:
2497 alert_dialog("File is currently executing", NULL, NULL);
2498 break;
2499
2500 case EFAULT:
2501 alert_dialog("Path points outside address space", NULL, NULL);
2502 break;
2503
2504 case EEXIST:
2505 alert_dialog("File already exists", NULL, NULL);
2506 break;
2507
2508 #ifndef TRUE_SYSV
2509 case EOPNOTSUPP :
2510 alert_dialog("Can't open a socket", NULL, NULL);
2511 break;
2512 #endif
2513 }
2514 }
2515 /*****************************************************************************
2516 * execwin_func *
2517 *****************************************************************************/
2518 /*ARGSUSED*/
execwin_func(w,current,call_data)2519 void execwin_func(w, current, call_data)
2520 Widget w;
2521 Fileinfo *current;
2522 XtPointer call_data;
2523 {
2524 extern Cursor busy;
2525
2526 AppProgram *node;
2527
2528 XtVaSetValues( current->fileInfoDialog, XtNcursor, busy, NULL ) ;
2529
2530 #ifdef DEBUG
2531 fprintf(stderr, "eb_input = %s\neb_output = %s\neb_error = %s\n",
2532 current->eb_input, current->eb_output, current->eb_error);
2533 #endif
2534
2535 /* compute_appnode loads node->string and node->program with
2536 dc_fullname. */
2537
2538 node = compute_appnode(current->dc_fullname, current);
2539
2540 /* say we want a pseudo-terminal */
2541 node->termopts = TERM;
2542
2543 #ifdef DEBUG
2544 fprintf(stderr, "execwin_func : node->program = %s\n",node->program);
2545 fprintf(stderr, "execwin_func : running...\n");
2546 #endif
2547
2548 /* Is a version is already running */
2549 if (node->count)
2550 popup_verify_app(node);
2551 else
2552 run_app(node, current->eb_input, current->eb_output, current->eb_error);
2553
2554 #ifdef DEBUG
2555 fprintf(stderr, "execwin_func : whew..\n");
2556 #endif
2557
2558 XtVaSetValues(
2559 current->fileInfoDialog,
2560 XtNcursor, NULL,
2561 NULL ) ;
2562 }
2563
2564 /*****************************************************************************
2565 * WM_execback_popdown *
2566 *****************************************************************************/
2567 #if NeedFunctionPrototypes
WM_execback_popdown(Widget w,Fileinfo * current,XEvent * event,Boolean * dispatch)2568 private void WM_execback_popdown(Widget w,
2569 Fileinfo *current,
2570 XEvent *event,
2571 Boolean *dispatch)
2572 #else
2573 private void WM_execback_popdown(w, current, event, dispatch)
2574 Widget w;
2575 Fileinfo *current;
2576 XEvent *event;
2577 Boolean *dispatch;
2578 #endif
2579 {
2580 extern Atom protocols[2]; /* defined in dialogs.c */
2581
2582 if (event->xclient.message_type == protocols[1] &&
2583 event->xclient.data.l[0] == protocols[0])
2584 /* the widget got a kill signal */
2585 {
2586 /* call callbacks on Cancel button */
2587 XtCallCallbacks(current->ebcommandcancel, XtNcallback, NULL);
2588 }
2589 }
2590
2591 /*****************************************************************************
2592 * execback_realize *
2593 *****************************************************************************/
2594 /*ARGSUSED*/
execback_realize(w,current,call_data)2595 void execback_realize(w, current, call_data)
2596 Widget w;
2597 Fileinfo *current;
2598 XtPointer call_data;
2599 {
2600
2601 XawTextSetInsertionPoint(current->ebtextinput, strlen(current->eb_input));
2602 XawTextSetInsertionPoint(current->ebtextoutput, strlen(current->eb_output));
2603 XawTextSetInsertionPoint(current->ebtexterror, strlen(current->eb_error));
2604
2605 realize_dialog(current->eb_popup, NULL, XtGrabNonexclusive,
2606 (XtEventHandler)WM_execback_popdown, current);
2607 }
2608
2609 /*****************************************************************************
2610 * execback_popdown *
2611 *****************************************************************************/
2612 /*ARGSUSED*/
execback_popdown(w,infobutton,call_data)2613 void execback_popdown(w, infobutton, call_data)
2614 Widget w;
2615 InfoButtons *infobutton;
2616 XtPointer call_data;
2617 {
2618 AppProgram *node;
2619 Fileinfo *current;
2620
2621 current = infobutton->fileinfo;
2622
2623 XtPopdown (current->eb_popup);
2624
2625 /* fprintf(stderr, "eb_input = %s\neb_output = %s\neb_error = %s\n", eb_input,
2626 eb_output, eb_error); */
2627
2628 if (infobutton->select == 1) {
2629 extern Cursor busy;
2630
2631 XtVaSetValues( current->fileInfoDialog, XtNcursor, busy, NULL ) ;
2632
2633 node = compute_appnode(current->dc_fullname, current);
2634 if (node->count)
2635 popup_verify_app(node);
2636 else
2637 run_app(node, current->eb_input, current->eb_output, current->eb_error);
2638
2639 XtVaSetValues( current->fileInfoDialog, XtNcursor, NULL, NULL ) ;
2640 }
2641 }
2642
2643 /*****************************************************************************
2644 * compute_appnode *
2645 * *
2646 * compute_appnode is used to find or generate an AppProgram node for *
2647 * <programname>. The AppProgram node is used in the application manager, *
2648 * which keeps a list of currently running processes. The AppProgram node *
2649 * holds four pieces of information relevant to our purposes here. *
2650 * *
2651 * node->string *
2652 * contains the name of the program we are executing. In this case, this *
2653 * includes the complete path to the file as well as the filename itself. *
2654 * e.g., /usr/bin/X11/xcolors. This field is used to test for the identity*
2655 * of the program being run. Routines which check to see if the user *
2656 * already has a copy of the program running check this field. *
2657 * This field is a label only, and need not contain the actual command *
2658 * used to invoke the program. *
2659 * *
2660 * The application manager knows that we provide a fully specified path in *
2661 * our identity field. If it sees node->options == IGNORE_SEL, it will *
2662 * take that as a sign that the node is ours, and will only display the *
2663 * last component of node->string in process lists. *
2664 * *
2665 * node->program *
2666 * contains the actual command used to invoke the program. *
2667 * *
2668 * node->options *
2669 * if IGNORE_SEL, application manager will not try to parse arguments for *
2670 * us, and will only display the last component of node->string in process *
2671 * lists. *
2672 * *
2673 * node->count *
2674 * maintains a count of the number of invokations of node->string running. *
2675 * *
2676 * *
2677 * *
2678 * Note: We never delete nodes. The assumption is that the user won't run *
2679 * five unique bajillion programs. Things get more complex if he does. *
2680 * *
2681 *****************************************************************************/
compute_appnode(programname,current)2682 private AppProgram *compute_appnode(programname, current)
2683 String programname;
2684 Fileinfo *current;
2685 {
2686 AppNode *ptr, *newptr;
2687 char *newstring ;
2688
2689 ptr = current->applist;
2690
2691 #ifdef DEBUG
2692 fprintf(stderr, "compute_appnode : starting %s\n", programname);
2693 fprintf(stderr,"compute_appnode : traversing dirman process list\n");
2694 #endif
2695
2696 /* Let's see if we've already allocated a node to handle this
2697 program. */
2698
2699 while (ptr && strcmp(ptr->node.string, programname)) {
2700
2701 #ifdef DEBUG
2702 fprintf(stderr, "compute_appnode : node.string = %s\n", ptr->node.string);
2703 fprintf(stderr, "compute_appnode : node.count = %d\n", ptr->node.count);
2704 #endif
2705
2706 ptr = ptr->next;
2707 }
2708
2709 #ifdef DEBUG
2710 fprintf(stderr,"compute_appnode : done traversing dirman process list\n");
2711 #endif
2712
2713 if (ptr) {
2714
2715 /* We don't want to change node.string, as that is
2716 our tag, but we do want to make sure our invocation
2717 is updated. */
2718
2719 #ifdef DEBUG
2720 fprintf(stderr, "compute_appnode : found existing node.\n\
2721 compute_appnode : node->program = %s\n",ptr->node.program);
2722 #endif
2723
2724 if (ptr->node.program) XtFree(ptr->node.program);
2725
2726 newstring = (char *) XtMalloc(strlen(programname));
2727 if (!newstring) {
2728 fprintf(stderr, "compute_appnode : newstring XtMalloc\n");
2729 exit(-1);
2730 }
2731 ptr->node.program = strcpy(newstring, programname);
2732
2733 #ifdef DEBUG
2734 fprintf(stderr, "\ncompute_appnode : programname = %s\n", programname);
2735 fprintf(stderr, "compute_appnode : now node->program = %s\n", ptr->node.program);
2736 #endif
2737
2738 return &(ptr->node);
2739 }
2740
2741 /* Otherwise allocate node, insert at the head of the list */
2742
2743 #ifdef DEBUG
2744 fprintf(stderr, "compute_appnode : allocating new node\n");
2745 #endif
2746
2747 newptr = (AppNode *) XtMalloc(sizeof(AppNode));
2748
2749 #ifdef DEBUG
2750 fprintf(stderr, "compute_appnode : newly minted node, node.program = %d\n",newptr->node.program);
2751 #endif
2752
2753 if (!newptr) {
2754 fprintf(stderr, "compute_appnode: Error in XtMalloc!\n");
2755 exit(-1);
2756 }
2757
2758 /* New node */
2759
2760 newstring = (char *) XtMalloc(strlen(programname));
2761 newptr->node.string = strcpy(newstring, programname);
2762 newptr->node.program = newptr->node.string;
2763 newptr->node.count = 0;
2764 newptr->node.icon = (Pixmap)NULL;
2765 newptr->node.options = IGNORE_SEL;
2766
2767 /* We'll insert it at the head of the list.. older progs
2768 will take longer to search for. */
2769
2770 newptr->next = current->applist;
2771 current->applist = newptr;
2772
2773 return &(newptr->node);
2774 }
2775
2776 /*****************************************************************************
2777 * update_func *
2778 *****************************************************************************/
2779 /*ARGSUSED*/
update_func(w,current,call_data)2780 void update_func(w, current, call_data)
2781 Widget w;
2782 Fileinfo *current;
2783 XtPointer call_data;
2784 {
2785 int group;
2786 struct passwd *pass;
2787 struct stat dummy_stat;
2788
2789 if (strcmp(current->edit_group, current->laststat.group))
2790 if ((group = group_number(current->edit_group)) == -1) {
2791 alert_dialog("Error", "Invalid group name.", NULL);
2792 strcpy(current->edit_group, current->laststat.group);
2793 load_text(current->form1c_text_group, current->edit_group);
2794 } else if (chown(current->dc_fullname, -1, group) == -1) {
2795 if (errno == EPERM)
2796 alert_dialog("Not a member of group requested", NULL, NULL);
2797 else alert_dialog("Error in chown(group)", NULL, NULL);
2798 strcpy(current->edit_group, current->laststat.group);
2799 load_text(current->form1c_text_group, current->edit_group);
2800 } else strcpy(current->laststat.group, current->edit_group);
2801
2802 if (strcmp(current->edit_filename, current->laststat.filename)) {
2803 char temp_name[1024], temp_name2[1024];
2804 strcpy(temp_name, current->dc_path);
2805 strcpy(temp_name2, current->dc_path);
2806 if (!stat(strcat(temp_name, current->edit_filename), &dummy_stat)) {
2807 char tempstring[80];
2808 ioerr_dialog(errno);
2809 sprintf(tempstring, "File %s already exists!",current->edit_filename);
2810 alert_dialog(tempstring, NULL, NULL);
2811 strcpy(current->edit_filename, current->laststat.filename);
2812 load_text(current->form1a_text_filename, current->edit_filename);
2813 } else if (rename(strcat(temp_name2, current->laststat.filename),
2814 temp_name) == -1) {
2815 alert_dialog("Error in rename", NULL, NULL);
2816 strcpy(current->edit_filename, current->laststat.filename);
2817 load_text(current->form1a_text_filename, current->edit_filename);
2818 } else /* Success! */ {
2819 strcpy(current->laststat.filename, current->edit_filename);
2820 strcpy(current->dc_filename, current->edit_filename);
2821 strcpy(current->dc_fullname, current->dc_path);
2822 strcat(current->dc_fullname, current->dc_filename);
2823 }
2824 }
2825
2826 if (strcmp(current->edit_owner, current->laststat.owner))
2827 if (!(pass=(getpwnam(current->edit_owner))) &&
2828 !(pass=(getpwuid((uid_t)atoi(current->edit_owner))))) {
2829 alert_dialog("No such user", current->edit_owner, NULL);
2830 strcpy(current->edit_owner, current->laststat.owner);
2831 load_text(current->form1c_text_owner, current->edit_owner);
2832 return;
2833 } else if (chown(current->dc_fullname, pass->pw_uid, -1) == -1) {
2834 alert_dialog("Error in chown(user)", NULL, NULL);
2835 strcpy(current->edit_owner, current->laststat.owner);
2836 load_text(current->form1c_text_owner, current->edit_owner);
2837 return;
2838 } else strcpy(current->laststat.owner, current->edit_owner);
2839
2840 /* Mark the update button as inoperative */
2841
2842 XtVaSetValues(
2843 current->form2b_command_update,
2844 XtNsensitive, False,
2845 NULL ) ;
2846
2847 update_buttons(UPDATE, current);
2848
2849 chmod(current->dc_fullname, current->filestat.st_mode);
2850
2851 /* Read the file status so we'll have the updated file
2852 modification time, etc. */
2853
2854 if (stat(current->dc_fullname, ¤t->filestat) == -1) {
2855 fprintf(stderr, "doubleclick:update_func:File status unreadable!\n");
2856 }
2857
2858 set_icon(current);
2859
2860 /* If our update takes us back to our initial mode, clear
2861 both undo buttons, else just clear our our undo button. */
2862
2863
2864 XtSetSensitive(current->form2b_command_reset,
2865 (
2866 ((current->laststat.mode = current->filestat.st_mode) == current->oldstat.mode) &&
2867 !strcmp(current->edit_filename, current->oldstat.filename) &&
2868 !strcmp(current->edit_group, current->oldstat.group) &&
2869 !strcmp(current->edit_owner, current->oldstat.owner)
2870 ) ? False : True);
2871
2872 XtSetSensitive(current->form2b_command_undo, False);
2873
2874 set_size_date(current);
2875 }
2876
2877 /*****************************************************************************
2878 * undo_func *
2879 *****************************************************************************/
2880 /*ARGSUSED*/
undo_func(w,infobutton,call_data)2881 void undo_func(w, infobutton, call_data)
2882 Widget w;
2883 InfoButtons *infobutton;
2884 XtPointer call_data;
2885 {
2886 int group;
2887 struct passwd *pass;
2888 Fileinfo *current;
2889 int mode;
2890
2891 mode = infobutton->mode;
2892 current = infobutton->fileinfo;
2893
2894 switch(mode) {
2895 case RESET:
2896 current->laststat.mode = current->filestat.st_mode = current->oldstat.mode;
2897
2898 if (strcmp(current->laststat.group, current->oldstat.group)) {
2899 if ((group = group_number(current->oldstat.group)) == -1) {
2900 alert_dialog("Error", "Impossibly Invalid group name.", NULL);
2901 strcpy(current->edit_group, current->laststat.group);
2902 load_text(current->form1c_text_group, current->edit_group);
2903 } else if (chown(current->dc_fullname, -1, group) == -1) {
2904 alert_dialog("Error in resetting group (chown)", NULL, NULL);
2905 strcpy(current->edit_group, current->laststat.group);
2906 load_text(current->form1c_text_group, current->edit_group);
2907 } else /* Success! */ {
2908 strcpy(current->edit_group, current->oldstat.group);
2909 strcpy(current->laststat.group, current->edit_group);
2910 load_text(current->form1c_text_group, current->edit_group);
2911 }
2912 } else if (strcmp(current->edit_group, current->oldstat.group)) {
2913 strcpy(current->edit_group, current->oldstat.group);
2914 load_text(current->form1c_text_group, current->edit_group);
2915 }
2916
2917 if (strcmp(current->laststat.filename, current->oldstat.filename))
2918 {
2919 char temp_name[1024], temp_name2[1024];
2920 strcpy(temp_name, current->dc_path);
2921 strcpy(temp_name2, current->dc_path);
2922 if (rename(strcat(temp_name, current->laststat.filename),
2923 strcat(temp_name2, current->oldstat.filename)) == -1) {
2924 alert_dialog("Error in resetting filename", NULL, NULL);
2925 strcpy(current->edit_filename, current->laststat.filename);
2926 load_text(current->form1a_text_filename, current->edit_filename);
2927 } else {
2928 strcpy(current->edit_filename, current->oldstat.filename);
2929 strcpy(current->laststat.filename, current->edit_filename);
2930 strcpy(current->dc_filename, current->edit_filename);
2931 strcpy(current->dc_fullname, current->dc_path);
2932 strcat(current->dc_fullname, current->dc_filename);
2933 load_text(current->form1a_text_filename, current->edit_filename);
2934 }
2935 } else if (strcmp(current->edit_filename, current->oldstat.filename)) {
2936 strcpy(current->edit_filename, current->oldstat.filename);
2937 strcpy(current->dc_filename, current->edit_filename);
2938 strcpy(current->dc_fullname, current->dc_path);
2939 strcat(current->dc_fullname, current->dc_filename);
2940 load_text(current->form1a_text_filename, current->edit_filename);
2941 }
2942
2943 if (strcmp(current->laststat.owner, current->oldstat.owner)) {
2944 if (!(pass=(getpwnam(current->oldstat.owner)))) {
2945 alert_dialog("Original user no longer exists!", NULL, NULL);
2946 strcpy(current->edit_owner, current->laststat.owner);
2947 load_text(current->form1c_text_owner, current->edit_owner);
2948 } else {
2949 if (chown(current->dc_fullname, pass->pw_uid, -1) == -1) {
2950 alert_dialog("Error in resetting owner (chown)", NULL, NULL);
2951 strcpy(current->edit_owner, current->laststat.owner);
2952 load_text(current->form1c_text_owner, current->edit_owner);
2953 } else /* Success! */ {
2954 strcpy(current->edit_owner, current->oldstat.owner);
2955 strcpy(current->laststat.owner, current->edit_owner);
2956 load_text(current->form1c_text_owner, current->edit_owner);
2957 }
2958 }
2959 } else if (strcmp(current->edit_owner, current->oldstat.owner)) {
2960 strcpy(current->edit_owner, current->oldstat.owner);
2961 load_text(current->form1c_text_owner, current->edit_owner);
2962 }
2963
2964 XtSetSensitive(current->form2b_command_reset, False);
2965 XtSetSensitive(current->form2b_command_undo, False);
2966 break;
2967
2968 case UNDO:
2969 current->filestat.st_mode = current->laststat.mode;
2970
2971 if (strcmp(current->edit_group, current->laststat.group)) {
2972 strcpy(current->edit_group, current->laststat.group);
2973 load_text(current->form1c_text_group, current->edit_group);
2974 }
2975
2976 if (strcmp(current->edit_filename, current->laststat.filename)) {
2977 strcpy(current->edit_filename, current->laststat.filename);
2978 load_text(current->form1a_text_filename, current->edit_filename);
2979 }
2980
2981 if (strcmp(current->edit_owner, current->laststat.owner)) {
2982 strcpy(current->edit_owner, current->laststat.owner);
2983 load_text(current->form1c_text_owner, current->edit_owner);
2984 }
2985
2986 XtSetSensitive(current->form2b_command_undo, False);
2987 XtSetSensitive(current->form2b_command_reset,
2988 ((current->filestat.st_mode == current->oldstat.mode) &&
2989 !strcmp(current->edit_filename, current->oldstat.filename) &&
2990 !strcmp(current->edit_group, current->oldstat.group) &&
2991 !strcmp(current->edit_owner, current->oldstat.owner)) ? False : True);
2992 }
2993
2994 /* Change the buttons back to their original state. */
2995
2996 update_buttons(UNDO, current);
2997
2998 XtSetSensitive(current->form2b_command_update, False);
2999
3000 /* Restore the permissions on disk to their original state. */
3001
3002 chmod(current->dc_fullname, current->filestat.st_mode);
3003
3004 set_icon(current);
3005
3006 set_size_date(current);
3007
3008 }
3009
3010 /*****************************************************************************
3011 * help_func *
3012 *****************************************************************************/
3013 /*ARGSUSED*/
help_func(w,client_data,call_data)3014 void help_func(w, client_data, call_data)
3015 Widget w;
3016 XtPointer client_data;
3017 XtPointer call_data;
3018 {
3019 if (access(perm_help_file, R_OK) == 0)
3020 displayfile(perm_help_file, NULL, "xdtm permissions help", XtGrabNone);
3021 else
3022 alert_dialog("Help file not found at", perm_help_file, "Cancel");
3023 }
3024
3025 /*****************************************************************************
3026 * group_number *
3027 *****************************************************************************/
group_number(groupname)3028 int group_number(groupname)
3029 char *groupname;
3030 {
3031 struct group *group;
3032
3033 setgrent ();
3034
3035 if (!(group=getgrnam(groupname)) && !(group=getgrgid(atoi(groupname))))
3036 return (-1);
3037 else
3038 return (group->gr_gid);
3039 }
3040
3041 /*****************************************************************************
3042 * user_is_member *
3043 *****************************************************************************/
user_is_member(gid)3044 int user_is_member( gid )
3045 gid_t gid ;
3046 {
3047 #ifdef SYSV
3048 gid_t gidset[NGROUPS];
3049 #else
3050 int gidset[NGROUPS];
3051 #endif
3052 int ngroups, i;
3053
3054 /* Get the list of groups that the user is in. */
3055
3056 #ifdef DEBUG
3057 fprintf(stderr, "Entering user_is_member()\n");
3058 fprintf(stderr, "gid = %d\n", gid);
3059 fflush(stderr);
3060 fprintf(stderr, "NGROUPS = %d\n", NGROUPS);
3061 #endif
3062
3063 ngroups = getgroups(NGROUPS, gidset);
3064
3065 #ifdef DEBUG
3066 fprintf(stderr, "Done getgroups\n");
3067 #endif
3068
3069 /* If we were able to successfully get the groups,
3070 check to see if the user is a member of group
3071 number gid. */
3072
3073 if (ngroups == -1) {
3074 fprintf(stderr, "xdtm: Error in reading groups in doubleclick.c:user_is_member \n");
3075 } else {
3076 #ifdef DEBUG
3077 fprintf(stderr, "ngroups = %d\n",ngroups);
3078 fflush(stderr);
3079 #endif
3080 for(i=0; i<ngroups; i++) {
3081 #ifdef DEBUG
3082 fprintf(stderr, "looping.. \n");
3083 fprintf(stderr, "gidset[%d] = %d\n", i, gidset[i]);
3084 fflush(stderr);
3085 #endif
3086 if (gidset[i] == gid) {
3087 #ifdef DEBUG
3088 fprintf(stderr, "return(1)\n");
3089 fflush(stderr);
3090 #endif
3091 return 1;
3092 }
3093 }
3094 }
3095 #ifdef DEBUG
3096 fprintf(stderr, "returning 0\n");
3097 fflush(stderr);
3098 #endif
3099 return 0;
3100 }
3101
3102 /*****************************************************************************
3103 * set_size_date *
3104 *****************************************************************************/
set_size_date(current)3105 private void set_size_date(current)
3106 Fileinfo *current;
3107 {
3108 strcpy(current->filedate,ctime(¤t->filestat.st_mtime));
3109 sprintf(current->filesize, "%9ld",current->filestat.st_size);
3110
3111 XtVaSetValues(
3112 current->form1b_label_date,
3113 XtNlabel, current->filedate,
3114 NULL ) ;
3115
3116 XtVaSetValues(
3117 current->form1b_label_size,
3118 XtNlabel, current->filesize,
3119 NULL ) ;
3120 }
3121
3122 /*****************************************************************************
3123 * set_icon *
3124 *****************************************************************************/
set_icon(current)3125 private void set_icon(current)
3126 Fileinfo *current;
3127 {
3128 Icon_mode save_mode;
3129
3130 save_mode.mode = current_mode.mode;
3131
3132 current_mode.mode = Icons;
3133
3134 /* getIconType will overwrite xdtmlist_element->string, free it before */
3135 if (current->xdtmlist_element->string)
3136 XtFree(current->xdtmlist_element->string);
3137
3138 if (!getIconType(current->dc_filename, current->dc_path,
3139 current->xdtmlist_element)) {
3140 fprintf(stderr, "doubleclick:File icon unreadable!\n");
3141 current->xdtmlist_element->icon = emptytick;
3142 }
3143
3144 XtVaSetValues(
3145 current->form1a_label_icon,
3146 XtNbitmap, current->xdtmlist_element->icon,
3147 NULL ) ;
3148
3149 current_mode.mode = save_mode.mode;
3150 }
3151
3152 /*****************************************************************************
3153 * load_text *
3154 *****************************************************************************/
load_text(w,string)3155 private void load_text(w, string)
3156 Widget w;
3157 char *string;
3158 {
3159 XtVaSetValues(
3160 w,
3161 XtNstring, string,
3162 NULL ) ;
3163
3164 XawTextSetInsertionPoint(w, strlen(string));
3165 }
3166