2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: ModAttrP.c /main/8 1999/12/09 13:07:16 mgreess $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 * COMPONENT_NAME: Desktop File Manager (dtfile)
31 * Description: Processing functions for the modify file attribute dialog.
33 * FUNCTIONS: AttrChangePipeCB
39 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
40 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
41 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
42 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
44 ****************************************************************************
45 ************************************<+>*************************************/
47 #if defined __osf__ || defined _AIX
58 #include <Xm/RowColumn.h>
60 #include <Dt/Connect.h>
66 #include "SharedProcs.h"
74 extern int mod_attr_dialog;
77 /* types of messages sent through the pipe */
78 #define PIPEMSG_DONE 1
80 /* callback data for pipe input handler */
90 /******** Static Function Declarations ********/
93 XtPointer client_data,
94 DialogData *old_dialog_data,
95 DialogData *new_dialog_data,
96 XtPointer call_data) ;
98 XtPointer client_data,
99 DialogData *old_dialog_data,
100 DialogData *new_dialog_data) ;
102 /******** End Static Function Declarations ********/
105 /************************************************************************
108 * Callback functions invoked from the Modify Attributes ... menu
109 * item. This function displays the file attribute dialog.
111 ************************************************************************/
116 XtPointer client_data,
119 FileMgrRec * file_mgr_rec;
120 DialogData * dialog_data;
121 FileMgrData * file_mgr_data;
122 DialogData * attr_dialog;
123 DirectorySet * directory_set;
124 FileViewData * file_view_data;
125 ModAttrRec *modAttr_rec;
128 char * errorMsg=NULL;
132 char * tmpStr, *tempStr;
136 if((int)client_data != NULL)
139 mbar = XmGetPostedFromWidget(XtParent(w));
141 XtSetArg(args[0], XmNuserData, &file_mgr_rec);
142 XtGetValues(mbar, args, 1);
144 /* Ignore accelerators when we're insensitive */
145 if (client_data == NULL)
146 if ((file_mgr_rec->menuStates & MODIFY) == 0)
149 /* Ignore accelerators received after we're unposted */
150 if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
152 file_mgr_data = (FileMgrData *) dialog_data->data;
154 /* get the file_view_data object from which the menu was invoked */
155 if (client_data == NULL)
156 file_view_data = NULL;
159 file_view_data = file_mgr_data->popup_menu_icon;
160 if (file_view_data == NULL)
161 /* the object has gone away (probably deleted) */
164 file_mgr_data->popup_menu_icon = NULL; /* Reset it, we don't need it */
168 attr_dialog = _DtGetDefaultDialogData (mod_attr_dialog);
170 file_mgr_rec->menuStates &= ~MODIFY;
171 if (file_view_data == NULL)
174 (DirectorySet *) file_mgr_data->selection_list[0]->directory_set;
176 /* Determine which file is selected */
177 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
178 file_mgr_data->selection_list[0]->file_data->file_name,
179 (ModAttrData *)attr_dialog->data);
184 (DirectorySet *)file_view_data->directory_set;
186 /* Determine which file is selected */
187 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
188 file_view_data->file_data->file_name,
189 (ModAttrData *)attr_dialog->data);
194 /* Get the initial attribute values for seleceted file */
195 _DtAddOneSubdialog (attr_dialog,
196 &file_mgr_data->attr_dialog_list,
197 &file_mgr_data->attr_dialog_count);
198 /* We need the file_mgr_rec inside the create routine so
199 * we attach it here for use later.
201 ((ModAttrData *) (attr_dialog->data))->main_widget = file_mgr_rec->main;
203 _DtShowDialog (file_mgr_rec->shell, NULL,
204 (XtPointer)file_mgr_rec, attr_dialog,
205 ModAttrChange, (XtPointer)file_mgr_rec, ModAttrClose,
206 (XtPointer)file_mgr_rec,NULL, False, False, NULL, NULL);
208 for(i = 0; i < file_mgr_data->attr_dialog_count; i++)
210 modAttr_rec = (ModAttrRec *)_DtGetDialogInstance(
211 file_mgr_data->attr_dialog_list[i]);
213 if(file_mgr_data->title != NULL &&
214 strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
216 tmpStr = GETMESSAGE(21, 1, "File Permissions");
217 tempStr = (char *)XtMalloc(strlen(tmpStr) +
218 strlen(file_mgr_data->title) + 5);
219 sprintf(tempStr, "%s - %s", file_mgr_data->title, tmpStr);
223 tmpStr = (GETMESSAGE(21,34, "File Manager - Permissions"));
224 tempStr = XtNewString(tmpStr);
226 XtSetArg (args[0], XmNtitle, tempStr);
227 XtSetValues (modAttr_rec->shell, args, 1);
233 /* Clean up used structures and put up an error dialog */
235 file_mgr_rec->menuStates |= MODIFY;
236 _DtFreeDialogData (attr_dialog);
238 tmpStr = GETMESSAGE(22, 4, "Cannot open object.");
239 errorMsg = XtNewString(tmpStr);
240 tmpStr = GETMESSAGE(22, 5, "Set Permissions Error");
241 title = XtNewString(tmpStr);
242 _DtMessage (file_mgr_rec->shell, title, errorMsg, NULL, HelpRequestCB);
251 /************************************************************************
254 * Callback functions invoked from the file attribute dialog's
255 * Ok button being pressed. This function updates the indicated
258 ************************************************************************/
260 /*--------------------------------------------------------------------
262 * Main routine of background process for AttrChange
263 *------------------------------------------------------------------*/
276 struct stat stat_buf;
282 /* get directory timestamp */
283 path = ResolveLocalPathName(host, directory, NULL,home_host_name, &tt_status);
284 if( TT_OK == tt_status )
286 if (stat(path, &stat_buf) == 0)
287 modify_time = stat_buf.st_mtime;
290 /* change the file attributes */
291 path = ResolveLocalPathName(host, directory, file, home_host_name, &tt_status);
292 if( TT_OK == tt_status )
294 if (chmod(path, mode) == 0)
297 chown(path, uid, gid);
305 /* send a 'done' msg through the pipe */
306 DPRINTF(("AttrChangeProcess: sending DONE, rc %d\n", rc));
307 pipe_msg = PIPEMSG_DONE;
308 write(pipe_fd, &pipe_msg, sizeof(short));
309 write(pipe_fd, &rc, sizeof(int));
310 write(pipe_fd, &modify_time, sizeof(long));
316 /*--------------------------------------------------------------------
318 * Read and process data sent through the pipe.
319 *------------------------------------------------------------------*/
323 XtPointer client_data,
327 AttrChangeCBData *cb_data = (AttrChangeCBData *)client_data;
329 char *title, *err_msg, *err_arg;
333 /* read the msg from the pipe */
335 n = PipeRead(*fd, &pipe_msg, sizeof(short));
337 if (pipe_msg == PIPEMSG_DONE)
339 PipeRead(*fd, &rc, sizeof(int));
340 PipeRead(*fd, &modify_time, sizeof(long));
344 fprintf(stderr, "Internal error in AttrChangePipeCB: bad pipe_msg %d\n",
350 DPRINTF(("AttrChangePipeCB: n %d, pipe_msg %d, rc %d\n", n, pipe_msg, rc));
352 /* if error, post error message */
355 err_msg = XtNewString(GETMESSAGE(22,3,"Cannot change properties for %s"));
356 FileOperationError(toplevel, err_msg, cb_data->file);
360 /* arrange for modified directory to be updated */
361 if (modify_time != 0)
362 DirectoryModifyTime(cb_data->host, cb_data->directory, modify_time);
363 DirectoryFileModified(cb_data->host, cb_data->directory, cb_data->file);
364 DirectoryEndModify(cb_data->host, cb_data->directory);
365 if(!strcmp(cb_data->file,".") || !strcmp(cb_data->file,".."))
368 char *tmpptr = strrchr(cb_data->directory,'/');
371 if(tmpptr != cb_data->directory)
372 tmpptr = NULL, dir = cb_data->directory;
375 DirectoryBeginModify(cb_data->host,dir);
376 DirectoryFileModified(cb_data->host,dir, tmpptr+1);
377 DirectoryEndModify(cb_data->host,dir);
385 char subdir_name[MAX_PATH + 1];
388 strcpy(subdir_name, cb_data->directory);
389 p = subdir_name + strlen(subdir_name);
393 strcpy(p, cb_data->file);
394 UpdateDirectory(NULL,cb_data->host, subdir_name);
397 /* close the pipe and cancel the callback */
401 /* free callback data */
402 XtFree(cb_data->host);
403 XtFree(cb_data->directory);
404 XtFree(cb_data->file);
405 XtFree((char *)cb_data);
409 /*--------------------------------------------------------------------
411 * Start the background process and set up callback for the pipe.
412 *------------------------------------------------------------------*/
416 XtPointer client_data,
417 DialogData *old_dialog_data,
418 DialogData *new_dialog_data,
419 XtPointer call_data )
421 static char *pname = "ModAttrChange";
422 AttrChangeCBData *cb_data;
423 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
424 ModAttrData * current;
434 /* Get current data */
435 current = (ModAttrData *) new_dialog_data->data;
436 old = (ModAttrData *) old_dialog_data->data;
438 /* see if anything has changed */
439 if (strcmp(current->owner, old->owner) == 0 &&
440 strcmp(current->group, old->group) == 0 &&
441 current->accessBits == old->accessBits &&
442 current->setuidBits == old->setuidBits)
444 /* nothing changed: close the dialog and return */
445 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
449 /* get new owner uid */
450 pw = getpwnam(current->owner);
453 else if (isdigit(current->owner[0]))
454 uid = atoi(current->owner);
458 /* get new group gid */
459 gr = getgrnam(current->group);
462 else if (isdigit(current->group[0]))
463 gid = atoi(current->group);
467 /* get new file mode */
468 mode = current->accessBits + current->setuidBits;
470 /* set up callback data */
471 cb_data = XtNew(AttrChangeCBData);
472 cb_data->host = XtNewString(current->host);
473 cb_data->directory = XtNewString(current->directory);
474 cb_data->file = XtNewString(current->name);
476 /* mark the directory as being modified in the directory cache */
477 DirectoryBeginModify(cb_data->host, cb_data->directory);
482 /* fork the process that does the actual work */
486 DirectoryAbortModify(cb_data->host, cb_data->directory);
488 "%s: fork failed, ppid %d, pid %d: error %d=%s\n",
489 pname, getppid(), getpid(), errno, strerror(errno));
496 DBGFORK(("%s: child forked, pipe %d\n", pname, pipe_fd[1]));
498 close(pipe_fd[0]); /* child won't read from the pipe */
500 rc = AttrChangeProcess(pipe_fd[1], cb_data->host, cb_data->directory,
501 cb_data->file, uid, gid, mode);
504 DBGFORK(("%s: child exiting (rc %d)\n", pname, rc));
509 DBGFORK(("%s: forked child<%d>, pipe %d\n", pname, pid, pipe_fd[0]));
511 /* parent: set up callback to get the pipe data */
512 close(pipe_fd[1]); /* parent won't write the pipe */
514 cb_data->child = pid;
516 XtAppAddInput(XtWidgetToApplicationContext(toplevel),
517 pipe_fd[0], (XtPointer)XtInputReadMask,
518 AttrChangePipeCB, (XtPointer)cb_data);
520 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
526 /************************************************************************
529 * Callback function invoked from the file attribute dialog's close
532 ************************************************************************/
536 XtPointer client_data,
537 DialogData *old_dialog_data,
538 DialogData *new_dialog_data )
540 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
541 FileMgrData * file_mgr_data;
542 DialogData * dialog_data;
548 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
549 file_mgr_data = (FileMgrData *) dialog_data->data;
551 if(file_mgr_data->selected_file_count > 0)
552 file_mgr_rec->menuStates |= MODIFY;
555 /* Remove the dialog data from the file managers list */
556 _DtHideOneSubdialog( old_dialog_data,
557 &file_mgr_data->attr_dialog_list,
558 &file_mgr_data->attr_dialog_count);
560 _DtHideDialog (old_dialog_data, False);
561 _DtFreeDialogData (old_dialog_data);
562 _DtFreeDialogData (new_dialog_data);