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 libraries 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 ************************************<+>*************************************/
58 #include <Xm/RowColumn.h>
60 #include <Dt/Connect.h>
62 #include <Dt/SharedProcs.h>
67 #include "SharedProcs.h"
75 extern int mod_attr_dialog;
78 /* types of messages sent through the pipe */
79 #define PIPEMSG_DONE 1
81 /* callback data for pipe input handler */
91 /******** Static Function Declarations ********/
94 XtPointer client_data,
95 DialogData *old_dialog_data,
96 DialogData *new_dialog_data,
97 XtPointer call_data) ;
99 XtPointer client_data,
100 DialogData *old_dialog_data,
101 DialogData *new_dialog_data) ;
103 /******** End Static Function Declarations ********/
106 /************************************************************************
109 * Callback functions invoked from the Modify Attributes ... menu
110 * item. This function displays the file attribute dialog.
112 ************************************************************************/
117 XtPointer client_data,
120 FileMgrRec * file_mgr_rec;
121 DialogData * dialog_data;
122 FileMgrData * file_mgr_data;
123 DialogData * attr_dialog;
124 DirectorySet * directory_set;
125 FileViewData * file_view_data;
126 ModAttrRec *modAttr_rec;
129 char * errorMsg=NULL;
133 char * tmpStr, *tempStr;
137 if((int)(XtArgVal)client_data != 0)
140 mbar = XmGetPostedFromWidget(XtParent(w));
142 XtSetArg(args[0], XmNuserData, &file_mgr_rec);
143 XtGetValues(mbar, args, 1);
145 /* Ignore accelerators when we're insensitive */
146 if (client_data == NULL)
147 if ((file_mgr_rec->menuStates & MODIFY) == 0)
150 /* Ignore accelerators received after we're unposted */
151 if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
153 file_mgr_data = (FileMgrData *) dialog_data->data;
155 /* get the file_view_data object from which the menu was invoked */
156 if (client_data == NULL)
157 file_view_data = NULL;
160 file_view_data = file_mgr_data->popup_menu_icon;
161 if (file_view_data == NULL)
162 /* the object has gone away (probably deleted) */
165 file_mgr_data->popup_menu_icon = NULL; /* Reset it, we don't need it */
169 attr_dialog = _DtGetDefaultDialogData (mod_attr_dialog);
171 file_mgr_rec->menuStates &= ~MODIFY;
172 if (file_view_data == NULL)
175 (DirectorySet *) file_mgr_data->selection_list[0]->directory_set;
177 /* Determine which file is selected */
178 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
179 file_mgr_data->selection_list[0]->file_data->file_name,
180 (ModAttrData *)attr_dialog->data);
185 (DirectorySet *)file_view_data->directory_set;
187 /* Determine which file is selected */
188 loadOk = LoadFileAttributes(file_mgr_data->host, directory_set->name,
189 file_view_data->file_data->file_name,
190 (ModAttrData *)attr_dialog->data);
195 /* Get the initial attribute values for seleceted file */
196 _DtAddOneSubdialog (attr_dialog,
197 &file_mgr_data->attr_dialog_list,
198 &file_mgr_data->attr_dialog_count);
199 /* We need the file_mgr_rec inside the create routine so
200 * we attach it here for use later.
202 ((ModAttrData *) (attr_dialog->data))->main_widget = file_mgr_rec->main;
204 _DtShowDialog (file_mgr_rec->shell, NULL,
205 (XtPointer)file_mgr_rec, attr_dialog,
206 ModAttrChange, (XtPointer)file_mgr_rec, ModAttrClose,
207 (XtPointer)file_mgr_rec,NULL, False, False, NULL, NULL);
209 for(i = 0; i < file_mgr_data->attr_dialog_count; i++)
211 modAttr_rec = (ModAttrRec *)_DtGetDialogInstance(
212 file_mgr_data->attr_dialog_list[i]);
214 if(file_mgr_data->title != NULL &&
215 strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
217 tmpStr = GETMESSAGE(21, 1, "File Permissions");
218 tempStr = (char *)XtMalloc(strlen(tmpStr) +
219 strlen(file_mgr_data->title) + 5);
220 sprintf(tempStr, "%s - %s", file_mgr_data->title, tmpStr);
224 tmpStr = (GETMESSAGE(21,34, "File Manager - Permissions"));
225 tempStr = XtNewString(tmpStr);
227 XtSetArg (args[0], XmNtitle, tempStr);
228 XtSetValues (modAttr_rec->shell, args, 1);
234 /* Clean up used structures and put up an error dialog */
236 file_mgr_rec->menuStates |= MODIFY;
237 _DtFreeDialogData (attr_dialog);
239 tmpStr = GETMESSAGE(22, 4, "Cannot open object.");
240 errorMsg = XtNewString(tmpStr);
241 tmpStr = GETMESSAGE(22, 5, "Set Permissions Error");
242 title = XtNewString(tmpStr);
243 _DtMessage (file_mgr_rec->shell, title, errorMsg, NULL, HelpRequestCB);
252 /************************************************************************
255 * Callback functions invoked from the file attribute dialog's
256 * Ok button being pressed. This function updates the indicated
259 ************************************************************************/
261 /*--------------------------------------------------------------------
263 * Main routine of background process for AttrChange
264 *------------------------------------------------------------------*/
277 struct stat stat_buf;
278 long modify_time = 0;
283 /* get directory timestamp */
284 path = ResolveLocalPathName(host, directory, NULL,home_host_name, &tt_status);
285 if( TT_OK == tt_status )
287 if (stat(path, &stat_buf) == 0)
288 modify_time = stat_buf.st_mtime;
291 /* change the file attributes */
292 path = ResolveLocalPathName(host, directory, file, home_host_name, &tt_status);
293 if( TT_OK == tt_status )
295 if (chmod(path, mode) == 0)
298 chown(path, uid, gid);
306 /* send a 'done' msg through the pipe */
307 DPRINTF(("AttrChangeProcess: sending DONE, rc %d\n", rc));
308 pipe_msg = PIPEMSG_DONE;
309 write(pipe_fd, &pipe_msg, sizeof(short));
310 write(pipe_fd, &rc, sizeof(int));
311 write(pipe_fd, &modify_time, sizeof(long));
317 /*--------------------------------------------------------------------
319 * Read and process data sent through the pipe.
320 *------------------------------------------------------------------*/
324 XtPointer client_data,
328 AttrChangeCBData *cb_data = (AttrChangeCBData *)client_data;
330 char *title, *err_msg, *err_arg;
334 /* read the msg from the pipe */
336 n = PipeRead(*fd, &pipe_msg, sizeof(short));
338 if (pipe_msg == PIPEMSG_DONE)
340 PipeRead(*fd, &rc, sizeof(int));
341 PipeRead(*fd, &modify_time, sizeof(long));
345 fprintf(stderr, "Internal error in AttrChangePipeCB: bad pipe_msg %d\n",
351 DPRINTF(("AttrChangePipeCB: n %d, pipe_msg %d, rc %d\n", n, pipe_msg, rc));
353 /* if error, post error message */
356 err_msg = XtNewString(GETMESSAGE(22,3,"Cannot change properties for %s"));
357 FileOperationError(toplevel, err_msg, cb_data->file);
361 /* arrange for modified directory to be updated */
362 if (modify_time != 0)
363 DirectoryModifyTime(cb_data->host, cb_data->directory, modify_time);
364 DirectoryFileModified(cb_data->host, cb_data->directory, cb_data->file);
365 DirectoryEndModify(cb_data->host, cb_data->directory);
366 if(!strcmp(cb_data->file,".") || !strcmp(cb_data->file,".."))
369 char *tmpptr = strrchr(cb_data->directory,'/');
372 if(tmpptr != cb_data->directory)
373 tmpptr = NULL, dir = cb_data->directory;
376 DirectoryBeginModify(cb_data->host,dir);
377 DirectoryFileModified(cb_data->host,dir, tmpptr+1);
378 DirectoryEndModify(cb_data->host,dir);
386 char subdir_name[MAX_PATH + 1];
389 strcpy(subdir_name, cb_data->directory);
390 p = subdir_name + strlen(subdir_name);
394 strcpy(p, cb_data->file);
395 UpdateDirectory(NULL,cb_data->host, subdir_name);
398 /* close the pipe and cancel the callback */
402 /* free callback data */
403 XtFree(cb_data->host);
404 XtFree(cb_data->directory);
405 XtFree(cb_data->file);
406 XtFree((char *)cb_data);
410 /*--------------------------------------------------------------------
412 * Start the background process and set up callback for the pipe.
413 *------------------------------------------------------------------*/
417 XtPointer client_data,
418 DialogData *old_dialog_data,
419 DialogData *new_dialog_data,
420 XtPointer call_data )
422 static char *pname = "ModAttrChange";
423 AttrChangeCBData *cb_data;
424 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
425 ModAttrData * current;
435 /* Get current data */
436 current = (ModAttrData *) new_dialog_data->data;
437 old = (ModAttrData *) old_dialog_data->data;
439 /* see if anything has changed */
440 if (strcmp(current->owner, old->owner) == 0 &&
441 strcmp(current->group, old->group) == 0 &&
442 current->accessBits == old->accessBits &&
443 current->setuidBits == old->setuidBits)
445 /* nothing changed: close the dialog and return */
446 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
450 /* get new owner uid */
451 pw = getpwnam(current->owner);
454 else if (isdigit(current->owner[0]))
455 uid = atoi(current->owner);
459 /* get new group gid */
460 gr = getgrnam(current->group);
463 else if (isdigit(current->group[0]))
464 gid = atoi(current->group);
468 /* get new file mode */
469 mode = current->accessBits + current->setuidBits;
471 /* set up callback data */
472 cb_data = XtNew(AttrChangeCBData);
473 cb_data->host = XtNewString(current->host);
474 cb_data->directory = XtNewString(current->directory);
475 cb_data->file = XtNewString(current->name);
477 /* mark the directory as being modified in the directory cache */
478 DirectoryBeginModify(cb_data->host, cb_data->directory);
483 /* fork the process that does the actual work */
487 DirectoryAbortModify(cb_data->host, cb_data->directory);
489 "%s: fork failed, ppid %d, pid %d: error %d=%s\n",
490 pname, getppid(), getpid(), errno, strerror(errno));
497 DBGFORK(("%s: child forked, pipe %d\n", pname, pipe_fd[1]));
499 close(pipe_fd[0]); /* child won't read from the pipe */
501 rc = AttrChangeProcess(pipe_fd[1], cb_data->host, cb_data->directory,
502 cb_data->file, uid, gid, mode);
505 DBGFORK(("%s: child exiting (rc %d)\n", pname, rc));
510 DBGFORK(("%s: forked child<%d>, pipe %d\n", pname, pid, pipe_fd[0]));
512 /* parent: set up callback to get the pipe data */
513 close(pipe_fd[1]); /* parent won't write the pipe */
515 cb_data->child = pid;
517 XtAppAddInput(XtWidgetToApplicationContext(toplevel),
518 pipe_fd[0], (XtPointer)XtInputReadMask,
519 AttrChangePipeCB, (XtPointer)cb_data);
521 ModAttrClose ((XtPointer)file_mgr_rec, old_dialog_data, new_dialog_data);
527 /************************************************************************
530 * Callback function invoked from the file attribute dialog's close
533 ************************************************************************/
537 XtPointer client_data,
538 DialogData *old_dialog_data,
539 DialogData *new_dialog_data )
541 FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
542 FileMgrData * file_mgr_data;
543 DialogData * dialog_data;
549 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
550 file_mgr_data = (FileMgrData *) dialog_data->data;
552 if(file_mgr_data->selected_file_count > 0)
553 file_mgr_rec->menuStates |= MODIFY;
556 /* Remove the dialog data from the file managers list */
557 _DtHideOneSubdialog( old_dialog_data,
558 &file_mgr_data->attr_dialog_list,
559 &file_mgr_data->attr_dialog_count);
561 _DtHideDialog (old_dialog_data, False);
562 _DtFreeDialogData (old_dialog_data);
563 _DtFreeDialogData (new_dialog_data);