1 /* $TOG: ModAttrP.c /main/8 1999/12/09 13:07:16 mgreess $ */
2 /************************************<+>*************************************
3 ****************************************************************************
7 * COMPONENT_NAME: Desktop File Manager (dtfile)
9 * Description: Processing functions for the modify file attribute dialog.
11 * FUNCTIONS: AttrChangePipeCB
17 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
18 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
19 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
20 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
22 ****************************************************************************
23 ************************************<+>*************************************/
25 #if defined __osf__ || defined _AIX
36 #include <Xm/RowColumn.h>
38 #include <Dt/Connect.h>
44 #include "SharedProcs.h"
52 extern int mod_attr_dialog;
55 /* types of messages sent through the pipe */
56 #define PIPEMSG_DONE 1
58 /* callback data for pipe input handler */
68 /******** Static Function Declarations ********/
71 XtPointer client_data,
72 DialogData *old_dialog_data,
73 DialogData *new_dialog_data,
74 XtPointer call_data) ;
76 XtPointer client_data,
77 DialogData *old_dialog_data,
78 DialogData *new_dialog_data) ;
80 /******** End Static Function Declarations ********/
83 /************************************************************************
86 * Callback functions invoked from the Modify Attributes ... menu
87 * item. This function displays the file attribute dialog.
89 ************************************************************************/
94 XtPointer client_data,
97 FileMgrRec * file_mgr_rec;
98 DialogData * dialog_data;
99 FileMgrData * file_mgr_data;
100 DialogData * attr_dialog;
101 DirectorySet * directory_set;
102 FileViewData * file_view_data;
103 ModAttrRec *modAttr_rec;
106 char * errorMsg=NULL;
110 char * tmpStr, *tempStr;
114 if((int)client_data != NULL)
117 mbar = XmGetPostedFromWidget(XtParent(w));
119 XtSetArg(args[0], XmNuserData, &file_mgr_rec);
120 XtGetValues(mbar, args, 1);
122 /* Ignore accelerators when we're insensitive */
123 if (client_data == NULL)
124 if ((file_mgr_rec->menuStates & MODIFY) == 0)
127 /* Ignore accelerators received after we're unposted */
128 if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
130 file_mgr_data = (FileMgrData *) dialog_data->data;
132 /* get the file_view_data object from which the menu was invoked */
133 if (client_data == NULL)
134 file_view_data = NULL;
137 file_view_data = file_mgr_data->popup_menu_icon;
138 if (file_view_data == NULL)
139 /* the object has gone away (probably deleted) */
142 file_mgr_data->popup_menu_icon = NULL; /* Reset it, we don't need it */
146 attr_dialog = _DtGetDefaultDialogData (mod_attr_dialog);
148 file_mgr_rec->menuStates &= ~MODIFY;
149 if (file_view_data == NULL)
152 (DirectorySet *) file_mgr_data->selection_list[0]->directory_set;
154 /* Determine which file is selected */
155 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
156 file_mgr_data->selection_list[0]->file_data->file_name,
157 (ModAttrData *)attr_dialog->data);
162 (DirectorySet *)file_view_data->directory_set;
164 /* Determine which file is selected */
165 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
166 file_view_data->file_data->file_name,
167 (ModAttrData *)attr_dialog->data);
172 /* Get the initial attribute values for seleceted file */
173 _DtAddOneSubdialog (attr_dialog,
174 &file_mgr_data->attr_dialog_list,
175 &file_mgr_data->attr_dialog_count);
176 /* We need the file_mgr_rec inside the create routine so
177 * we attach it here for use later.
179 ((ModAttrData *) (attr_dialog->data))->main_widget = file_mgr_rec->main;
181 _DtShowDialog (file_mgr_rec->shell, NULL,
182 (XtPointer)file_mgr_rec, attr_dialog,
183 ModAttrChange, (XtPointer)file_mgr_rec, ModAttrClose,
184 (XtPointer)file_mgr_rec,NULL, False, False, NULL, NULL);
186 for(i = 0; i < file_mgr_data->attr_dialog_count; i++)
188 modAttr_rec = (ModAttrRec *)_DtGetDialogInstance(
189 file_mgr_data->attr_dialog_list[i]);
191 if(file_mgr_data->title != NULL &&
192 strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
194 tmpStr = GETMESSAGE(21, 1, "File Permissions");
195 tempStr = (char *)XtMalloc(strlen(tmpStr) +
196 strlen(file_mgr_data->title) + 5);
197 sprintf(tempStr, "%s - %s", file_mgr_data->title, tmpStr);
201 tmpStr = (GETMESSAGE(21,34, "File Manager - Permissions"));
202 tempStr = XtNewString(tmpStr);
204 XtSetArg (args[0], XmNtitle, tempStr);
205 XtSetValues (modAttr_rec->shell, args, 1);
211 /* Clean up used structures and put up an error dialog */
213 file_mgr_rec->menuStates |= MODIFY;
214 _DtFreeDialogData (attr_dialog);
216 tmpStr = GETMESSAGE(22, 4, "Cannot open object.");
217 errorMsg = XtNewString(tmpStr);
218 tmpStr = GETMESSAGE(22, 5, "Set Permissions Error");
219 title = XtNewString(tmpStr);
220 _DtMessage (file_mgr_rec->shell, title, errorMsg, NULL, HelpRequestCB);
229 /************************************************************************
232 * Callback functions invoked from the file attribute dialog's
233 * Ok button being pressed. This function updates the indicated
236 ************************************************************************/
238 /*--------------------------------------------------------------------
240 * Main routine of background process for AttrChange
241 *------------------------------------------------------------------*/
254 struct stat stat_buf;
260 /* get directory timestamp */
261 path = ResolveLocalPathName(host, directory, NULL,home_host_name, &tt_status);
262 if( TT_OK == tt_status )
264 if (stat(path, &stat_buf) == 0)
265 modify_time = stat_buf.st_mtime;
268 /* change the file attributes */
269 path = ResolveLocalPathName(host, directory, file, home_host_name, &tt_status);
270 if( TT_OK == tt_status )
272 if (chmod(path, mode) == 0)
275 chown(path, uid, gid);
283 /* send a 'done' msg through the pipe */
284 DPRINTF(("AttrChangeProcess: sending DONE, rc %d\n", rc));
285 pipe_msg = PIPEMSG_DONE;
286 write(pipe_fd, &pipe_msg, sizeof(short));
287 write(pipe_fd, &rc, sizeof(int));
288 write(pipe_fd, &modify_time, sizeof(long));
294 /*--------------------------------------------------------------------
296 * Read and process data sent through the pipe.
297 *------------------------------------------------------------------*/
301 XtPointer client_data,
305 AttrChangeCBData *cb_data = (AttrChangeCBData *)client_data;
307 char *title, *err_msg, *err_arg;
311 /* read the msg from the pipe */
313 n = PipeRead(*fd, &pipe_msg, sizeof(short));
315 if (pipe_msg == PIPEMSG_DONE)
317 PipeRead(*fd, &rc, sizeof(int));
318 PipeRead(*fd, &modify_time, sizeof(long));
322 fprintf(stderr, "Internal error in AttrChangePipeCB: bad pipe_msg %d\n",
328 DPRINTF(("AttrChangePipeCB: n %d, pipe_msg %d, rc %d\n", n, pipe_msg, rc));
330 /* if error, post error message */
333 err_msg = XtNewString(GETMESSAGE(22,3,"Cannot change properties for %s"));
334 FileOperationError(toplevel, err_msg, cb_data->file);
338 /* arrange for modified directory to be updated */
339 if (modify_time != 0)
340 DirectoryModifyTime(cb_data->host, cb_data->directory, modify_time);
341 DirectoryFileModified(cb_data->host, cb_data->directory, cb_data->file);
342 DirectoryEndModify(cb_data->host, cb_data->directory);
343 if(!strcmp(cb_data->file,".") || !strcmp(cb_data->file,".."))
346 char *tmpptr = strrchr(cb_data->directory,'/');
349 if(tmpptr != cb_data->directory)
350 tmpptr = NULL, dir = cb_data->directory;
353 DirectoryBeginModify(cb_data->host,dir);
354 DirectoryFileModified(cb_data->host,dir, tmpptr+1);
355 DirectoryEndModify(cb_data->host,dir);
363 char subdir_name[MAX_PATH + 1];
366 strcpy(subdir_name, cb_data->directory);
367 p = subdir_name + strlen(subdir_name);
371 strcpy(p, cb_data->file);
372 UpdateDirectory(NULL,cb_data->host, subdir_name);
375 /* close the pipe and cancel the callback */
379 /* free callback data */
380 XtFree(cb_data->host);
381 XtFree(cb_data->directory);
382 XtFree(cb_data->file);
383 XtFree((char *)cb_data);
387 /*--------------------------------------------------------------------
389 * Start the background process and set up callback for the pipe.
390 *------------------------------------------------------------------*/
394 XtPointer client_data,
395 DialogData *old_dialog_data,
396 DialogData *new_dialog_data,
397 XtPointer call_data )
399 static char *pname = "ModAttrChange";
400 AttrChangeCBData *cb_data;
401 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
402 ModAttrData * current;
412 /* Get current data */
413 current = (ModAttrData *) new_dialog_data->data;
414 old = (ModAttrData *) old_dialog_data->data;
416 /* see if anything has changed */
417 if (strcmp(current->owner, old->owner) == 0 &&
418 strcmp(current->group, old->group) == 0 &&
419 current->accessBits == old->accessBits &&
420 current->setuidBits == old->setuidBits)
422 /* nothing changed: close the dialog and return */
423 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
427 /* get new owner uid */
428 pw = getpwnam(current->owner);
431 else if (isdigit(current->owner[0]))
432 uid = atoi(current->owner);
436 /* get new group gid */
437 gr = getgrnam(current->group);
440 else if (isdigit(current->group[0]))
441 gid = atoi(current->group);
445 /* get new file mode */
446 mode = current->accessBits + current->setuidBits;
448 /* set up callback data */
449 cb_data = XtNew(AttrChangeCBData);
450 cb_data->host = XtNewString(current->host);
451 cb_data->directory = XtNewString(current->directory);
452 cb_data->file = XtNewString(current->name);
454 /* mark the directory as being modified in the directory cache */
455 DirectoryBeginModify(cb_data->host, cb_data->directory);
460 /* fork the process that does the actual work */
464 DirectoryAbortModify(cb_data->host, cb_data->directory);
466 "%s: fork failed, ppid %d, pid %d: error %d=%s\n",
467 pname, getppid(), getpid(), errno, strerror(errno));
474 DBGFORK(("%s: child forked, pipe %d\n", pname, pipe_fd[1]));
476 close(pipe_fd[0]); /* child won't read from the pipe */
478 rc = AttrChangeProcess(pipe_fd[1], cb_data->host, cb_data->directory,
479 cb_data->file, uid, gid, mode);
482 DBGFORK(("%s: child exiting (rc %d)\n", pname, rc));
487 DBGFORK(("%s: forked child<%d>, pipe %d\n", pname, pid, pipe_fd[0]));
489 /* parent: set up callback to get the pipe data */
490 close(pipe_fd[1]); /* parent won't write the pipe */
492 cb_data->child = pid;
494 XtAppAddInput(XtWidgetToApplicationContext(toplevel),
495 pipe_fd[0], (XtPointer)XtInputReadMask,
496 AttrChangePipeCB, (XtPointer)cb_data);
498 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
504 /************************************************************************
507 * Callback function invoked from the file attribute dialog's close
510 ************************************************************************/
514 XtPointer client_data,
515 DialogData *old_dialog_data,
516 DialogData *new_dialog_data )
518 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
519 FileMgrData * file_mgr_data;
520 DialogData * dialog_data;
526 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
527 file_mgr_data = (FileMgrData *) dialog_data->data;
529 if(file_mgr_data->selected_file_count > 0)
530 file_mgr_rec->menuStates |= MODIFY;
533 /* Remove the dialog data from the file managers list */
534 _DtHideOneSubdialog( old_dialog_data,
535 &file_mgr_data->attr_dialog_list,
536 &file_mgr_data->attr_dialog_count);
538 _DtHideDialog (old_dialog_data, False);
539 _DtFreeDialogData (old_dialog_data);
540 _DtFreeDialogData (new_dialog_data);