dthelp: Change to ANSI function definitions
[oweals/cde.git] / cde / programs / dtfile / Trash.c
index b2ca7beaef614ceae2bdcbf8e84918968734baf9..ad792753770d597bfc47152eeb64f618bcb92aa9 100644 (file)
@@ -1,3 +1,25 @@
+/*
+ * CDE - Common Desktop Environment
+ *
+ * Copyright (c) 1993-2012, The Open Group. All rights reserved.
+ *
+ * These libraries and programs are free software; you can
+ * redistribute them and/or modify them under the terms of the GNU
+ * Lesser General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * These libraries and programs are distributed in the hope that
+ * they will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with these libraries and programs; if not, write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+ * Floor, Boston, MA 02110-1301 USA
+ */
 /* $TOG: Trash.c /main/12 1999/12/09 13:07:25 mgreess $ */
 /************************************<+>*************************************
  ****************************************************************************
 #include <dirent.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdint.h>
+#if defined(CSRG_BASED)
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
 #include <ustat.h>
+#endif
 
 #include <Xm/RowColumn.h>
 #include <Xm/CascadeB.h>
 #include <Dt/EnvControlP.h>
 #include <Dt/Wsm.h>
 #include <Dt/Dnd.h>
+#include <Dt/SharedProcs.h>
+#include "DtSvcInternal.h" /* _DtGetMask */
 
 #include <Tt/tttk.h>
 
 #include "Desktop.h"
 #include "Main.h"
 #include "SharedMsgs.h"
+#include "dtcopy/fsrtns.h"
 
 #define AdditionalHeader (GETMESSAGE(27,98, "(Plus %d additional object(s))"))
 
@@ -217,6 +248,12 @@ Widget trashShell;
 DialogData * primaryTrashHelpDialog = NULL;
 DialogData ** secondaryTrashHelpDialogList = NULL;
 int secondaryTrashHelpDialogCount = 0;
+
+/* Forward prototype */
+int EraseDir(char *dir_name);
+/* From dtcopy/fsrtns.c */
+extern int EmptyDir(char *sourceP, int rm, int force);
+
                                             /* 'defines' for trash files */
 static char * TRASH_DIR = ".dt/Trash";
 static char * TRASH_INFO_FILE = ".dt/Trash/.trashinfo";
@@ -668,10 +705,14 @@ WriteTrashEntries( void )
 
       /* Remove the original information file, and move the new one */
       (void) fclose(newFile);
-      (void) chown(NewTrashInfoFileName, getuid(), getgid());
+      if(-1 == chown(NewTrashInfoFileName, getuid(), getgid())) {
+         return( False );      
+      }
       (void) remove(TrashInfoFileName);
       (void) rename(NewTrashInfoFileName, TrashInfoFileName);
-      (void) chown(TrashInfoFileName, getuid(), getgid());
+      if(-1 == chown(TrashInfoFileName, getuid(), getgid())) {
+         return( False );      
+      }
       return( True );
    }
    else
@@ -731,7 +772,7 @@ CreateTrashMenu(
       trashMenu[i].helpData = NULL;
       trashMenu[i].activateCallback = NULL;
       trashMenu[i].activateData = NULL;
-      trashMenu[i].maskBit = NULL;
+      trashMenu[i].maskBit = 0;
       trashMenu[i].isHelpBtn = False;
       trashMenu[i].label = NULL;
       trashMenu[i].mnemonic = NULL;
@@ -1185,7 +1226,7 @@ TrashEmpty(void)
       Select_All(*selectAllBtn, NULL, NULL);
       Remove(*removeBtn, NULL, NULL);
 */
-      EmptyDir(trashFileMgrData->current_directory,0);
+      EmptyDir(trashFileMgrData->current_directory,0,0);
    }
 }
 
@@ -2672,7 +2713,7 @@ MoveToTrashProcess(
    DIR * dirp;
    struct dirent * entry;
    Boolean success;
-   int i, rc;
+   int i, rc, rv;
    char savechar;
 
    for (i = 0; i < file_count; i++)
@@ -2687,8 +2728,8 @@ MoveToTrashProcess(
          pipe_msg = PIPEMSG_OTHER_ERROR;
          rc = BAD_FILE_ERROR;
          DPRINTF(("MoveToTrashProcess: sending BAD_FILE_ERROR\n"));
-         write(pipe_fd, &pipe_msg, sizeof(short));
-         write(pipe_fd, &rc, sizeof(int));
+         rv = write(pipe_fd, &pipe_msg, sizeof(short));
+         rv = write(pipe_fd, &rc, sizeof(int));
          continue;
       }
       if (path && MatchesSacredDirectory(path))
@@ -2698,8 +2739,8 @@ MoveToTrashProcess(
          pipe_msg = PIPEMSG_OTHER_ERROR;
          rc = BAD_FILE_SACRED;
          DPRINTF(("MoveToTrashProcess: sending BAD_FILE_SACRED\n"));
-         write(pipe_fd, &pipe_msg, sizeof(short));
-         write(pipe_fd, &rc, sizeof(int));
+         rv = write(pipe_fd, &pipe_msg, sizeof(short));
+         rv = write(pipe_fd, &rc, sizeof(int));
          continue;
       }
 
@@ -2737,8 +2778,8 @@ MoveToTrashProcess(
            XtFree(path);
            pipe_msg = PIPEMSG_OTHER_ERROR;
            DPRINTF(("MoveToTrashProcess: sending BAD_TRASH message\n"));
-           write(pipe_fd, &pipe_msg, sizeof(short));
-           write(pipe_fd, &rc, sizeof(int));
+           rv = write(pipe_fd, &pipe_msg, sizeof(short));
+           rv = write(pipe_fd, &rc, sizeof(int));
            continue;
          }
          else if (CheckAccess(path, W_OK) != 0 && !S_ISLNK(s1.st_mode))
@@ -2748,8 +2789,8 @@ MoveToTrashProcess(
             pipe_msg = PIPEMSG_OTHER_ERROR;
             rc = VERIFY_FILE;
             DPRINTF(("MoveToTrashProcess: sending VERIFY_FILE\n"));
-            write(pipe_fd, &pipe_msg, sizeof(short));
-            write(pipe_fd, &rc, sizeof(int));
+            rv = write(pipe_fd, &pipe_msg, sizeof(short));
+            rv = write(pipe_fd, &rc, sizeof(int));
             continue;
          }
 
@@ -2783,8 +2824,8 @@ MoveToTrashProcess(
                pipe_msg = PIPEMSG_OTHER_ERROR;
                rc = VERIFY_DIR;
                DPRINTF(("MoveToTrashProcess: sending VERIFY_DIR\n"));
-               write(pipe_fd, &pipe_msg, sizeof(short));
-               write(pipe_fd, &rc, sizeof(int));
+               rv = write(pipe_fd, &pipe_msg, sizeof(short));
+               rv = write(pipe_fd, &rc, sizeof(int));
                continue;
             }
          }
@@ -2794,13 +2835,13 @@ MoveToTrashProcess(
       to = CreateTrashFilename(baseName, TRUE);
 
       /* move file to the trash directory */
-      success = FileManip((Widget)pipe_fd, MOVE_FILE, path, to, TRUE,
+      success = FileManip((Widget) (intptr_t) pipe_fd, MOVE_FILE, path, to, TRUE,
                           FileOpError, True, TRASH_DIRECTORY);
       if (success)
       {
          pipe_msg = PIPEMSG_DONE;
          DPRINTF(("MoveToTrashProcess: sending DONE\n"));
-         write(pipe_fd, &pipe_msg, sizeof(short));
+         rv = write(pipe_fd, &pipe_msg, sizeof(short));
          PipeWriteString(pipe_fd, path);
          PipeWriteString(pipe_fd, to);
       }
@@ -3330,7 +3371,12 @@ MoveToTrash(
 #endif /* SUN_PERF */
 
    /* create a pipe */
-   pipe(pipe_fd);
+   if(-1 == pipe(pipe_fd)) {
+       fprintf(stderr,
+               "%s:  pipe failed error %d=%s\n",
+               pname, errno, strerror(errno));
+       return;
+   }
 
    /* fork the process that does the actual work */
    pid = fork();
@@ -3402,7 +3448,7 @@ RestoreProcess(
        int *rc,
        Boolean CheckedAlready)
 {
-   int i, j;
+   int i, j, rv;
    char *full_dirname;
    char *from, *to;
    char *ptr;
@@ -3423,8 +3469,8 @@ RestoreProcess(
         pipe_msg = PIPEMSG_DONE;
         rc[0] = -1;
         DPRINTF(("RestoreProcess: Unable to Resolve local path name\n"));
-        write(pipe_fd, &pipe_msg, sizeof(short));
-        write(pipe_fd, rc, sizeof(int));
+        rv = write(pipe_fd, &pipe_msg, sizeof(short));
+        rv = write(pipe_fd, rc, sizeof(int));
         return;
       }
    }
@@ -3476,7 +3522,7 @@ RestoreProcess(
       if (to != NULL)
       {
 
-         status = RestoreObject((Widget)pipe_fd, MOVE_FILE, from,to,
+         status = RestoreObject((Widget) (intptr_t) pipe_fd, MOVE_FILE, from,to,
                        TRUE, FileOpError, False, NOT_DESKTOP,CheckedAlready);
          /* restore was successful */
          if(status == (int) True)
@@ -3494,8 +3540,8 @@ RestoreProcess(
    /* send return codes back trough the pipe */
    pipe_msg = PIPEMSG_DONE;
    DPRINTF(("RestoreProcess: sending DONE\n"));
-   write(pipe_fd, &pipe_msg, sizeof(short));
-   write(pipe_fd, rc, file_count * sizeof(int));
+   rv = write(pipe_fd, &pipe_msg, sizeof(short));
+   rv = write(pipe_fd, rc, file_count * sizeof(int));
 
    XtFree(full_dirname);
 }
@@ -3720,7 +3766,12 @@ RestoreFromTrash(
    cb_data->msg = msg;
 
    /* create a pipe */
-   pipe(pipe_fd);
+   if(-1 == pipe(pipe_fd)) {
+       fprintf(stderr,
+               "%s: pipe failed, error %d=%s\n",
+               pname, errno, strerror(errno));
+       return;
+   }
 
    /* fork the process that does the actual work */
    pid = fork();
@@ -3781,7 +3832,7 @@ EmptyTrashProcess(
        int del_count,
        int *rc)
 {
-   int i;
+   int i, rv;
    short pipe_msg;
 
    /*
@@ -3797,8 +3848,8 @@ EmptyTrashProcess(
    /* send return codes back trough the pipe */
    pipe_msg = PIPEMSG_DONE;
    DPRINTF(("EmptyTrashProcess: sending DONE\n"));
-   write(pipe_fd, &pipe_msg, sizeof(short));
-   write(pipe_fd, rc, del_count * sizeof(int));
+   rv = write(pipe_fd, &pipe_msg, sizeof(short));
+   rv = write(pipe_fd, rc, del_count * sizeof(int));
 }
 
 
@@ -4040,7 +4091,12 @@ EmptyTrash(
    cb_data->msg = msg;
 
    /* create a pipe */
-   pipe(pipe_fd);
+   if(-1 == pipe(pipe_fd)) {
+       fprintf(stderr,
+               "%s: pipe failed, error %d=%s\n",
+               pname, errno, strerror(errno));
+       return;
+   }
 
    /* fork the process that does the actual work */
    pid = fork();
@@ -4084,24 +4140,51 @@ CheckDeletePermission(
   char *parentdir,
   char *destinationPath)
 {
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+  struct statfs statbuf;
+#elif defined(__NetBSD__)
+  struct statvfs statbuf;
+#else
   struct stat statbuf;
+#endif
   char fname[1024];
 
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+  if (statfs(parentdir,&statbuf) < 0)  /* does not exist */
+#elif defined(__NetBSD__)
+  if (statvfs(parentdir,&statbuf) < 0)  /* does not exist */
+#else
   if (lstat(parentdir,&statbuf) < 0)  /* does not exist */
+#endif
     return -1;
 
   /* check if we are root */
   if (getuid() == 0)
   {
     /* if NFS, need to check if server trusts root */
+#if defined(CSRG_BASED)
+    if (!strcmp(statbuf.f_fstypename, "nfs"))  /* Root user and nfs */
+#else
     if (FileSysType(statbuf.st_dev) < 0)  /* Root user and nfs */
+#endif
     {
+       int fd = -1;
        char *tmpfile;
-       tmpfile = tempnam(parentdir,"quang");
-       if (creat(tmpfile,O_RDONLY)< 0)         /* Create a temporary file */
-          return -1;
+       tmpfile = tempnam(parentdir,"dtfile");
+       if (!tmpfile)
+           return -1;
+       if ((fd = creat(tmpfile,O_RDONLY)) < 0)  /* Create a temporary file */
+       {
+           free(tmpfile);
+           return -1;
+       }
+       close(fd);
        if (remove(tmpfile) < 0)                /* Delete the created file */
-          return -1;
+       {
+           free(tmpfile);
+           return -1;
+       }
+       free(tmpfile);
     }
 
     /* root user can delete anything */
@@ -4151,8 +4234,10 @@ CheckDeletePermissionRecur(
       if (first_file)
       {
         /* check for write permission in this directory */
-        if (CheckAccess(destinationPath, W_OK|X_OK) < 0)
+        if (CheckAccess(destinationPath, W_OK|X_OK) < 0) {
+          closedir(dirp);
           return -1;
+        }
 
         /* append a '/' to the end of directory name */
         fnamep = destinationPath + strlen(destinationPath);
@@ -4166,13 +4251,20 @@ CheckDeletePermissionRecur(
 
       /* recursively check permission on this file */
       if (CheckDeletePermissionRecur(destinationPath))
-        return -1;
+      {
+          closedir(dirp);
+          return -1;
+      }
+
     }
   }
 
+  closedir(dirp);
+
   return 0;
 }
 
+#if !defined(CSRG_BASED)
 static int
 FileSysType(
    int dev)
@@ -4182,6 +4274,7 @@ FileSysType(
      return -2;
   return u1.f_tinode;
 }
+#endif
 
 static int
 RestoreObject(
@@ -4197,7 +4290,8 @@ RestoreObject(
 {
   struct stat statsrc,stattar;
   Boolean status;
-  char *localdir,*chrptr;
+  char *localdir = NULL,*chrptr;
+  int rv;
 
   if(!CheckedAlready)
   {
@@ -4217,14 +4311,19 @@ RestoreObject(
     }
     if(stat(target,&stattar) >= 0)  /* Target exists  */
     {
-       if(CheckDeletePermission(localdir,target))
+       if(CheckDeletePermission(localdir,target)) {
+         free(localdir);
          return ((int)False);
-       else
+       } else {
+         free(localdir);
          return SKIP_FILE;
+       }
     }
   }
+
+  free(localdir);
   return ((int )FileManip((Widget)w, MOVE_FILE, source, target, TRUE,
-                                  FileOpError, False, NOT_DESKTOP));
+                          FileOpError, False, NOT_DESKTOP));
 }
 static void
 CreateRestoreDialog(
@@ -4289,7 +4388,7 @@ RestoreVerifyOk(
 
       if(lstat(dirs[1],&s1) < 0)
          goto goback;
-      fsErase(dirs[1],&status);
+      fsErase(dirs[1],&status,0);
       FileList = (char **) XtMalloc(sizeof(char *));
       FileList[0] = XtNewString(dirs[0]);
       RestoreFromTrash(FileList, (int) 1, NULL, NULL, NULL,True);