/*****************************************************************************
 *  Backup Copy                                                              *
 *  Programmed by: Kevin Lindsay                                             *
 *  Copyright (c) 1998 NetNation Communications Inc                          *
 * ***************************************************************************/ 

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <fcntl.h> 

#include "link.h"
#include "rmrec.h"
#include "statmalloc.h"
#include "errno.h"
#include "rmrec.h"
#include "misc.h"
#include "config.h"

#ifdef LINUX_CPBK
#include <asm/types.h>
#endif

int
trashit(char *filename,int dest_fd, int TRASHFD, char *progname, char ttype, char *trash_src_dir, F_MODE TDIRMODE)
{
   char *cwd;
   char *dirname;
   int jump = 0;
   char *ptr1;
   char *ptr2;
   char *tptr1=NULL;
   char *tptr2=NULL;
   char *oldlink;
   char *newlink;
   struct stat destfs;
   struct stat flink;
   int ifexist;
   int linkbytes;
   char symbuf[MYPATH_MAX];
   char *MYcwd;
   int sdlen;
   char *tempcwd;
   int tmpcwdlen;
   
   if (fchdir(dest_fd) == -1) {
      fprintf(stderr,"%s: trash bin: %s\n",progname,strerror(errno));
      return(-1);
   }
   
   lstat(filename,&destfs);
   
   tempcwd = MYgetcwd();
   
   tmpcwdlen = strlen(tempcwd);
   
   ptr1 = strrchr(tempcwd,'/')+1;
   ptr2 = ptr1;   
   
   while (ptr2 < tempcwd + tmpcwdlen)
       ptr2++;
   
   sdlen = strlen(trash_src_dir);
   
   if (sdlen == 0)
       cwd = (char *)statmalloc(2);
   else {
      tptr1 = strchr(trash_src_dir,'/')+1;
      tptr2 = trash_src_dir + sdlen;
      cwd = (char *)statmalloc((tptr2-tptr1)+(ptr2-ptr1)+2);
   }
   
   cwd[0] = '/';
   cwd[1] = '\0';
   
   if (sdlen != 0) {
      strncat(cwd,tptr1,tptr2-tptr1);
      strncat(cwd,ptr1,ptr2-ptr1);
   }
   
   /*   printf("CWD: %s\n",cwd);
    printf("TCWD: %s\n",tempcwd);
    printf("Trash: %s\n",trash_src_dir); */
   
   if (fchdir(TRASHFD) == -1) {
      fprintf(stderr,"%s: trash bin: chdir: %s\n",progname,strerror(errno));
      freemalloc(cwd);
      return(-1);
   }
   
   ptr1 = cwd+1;
   oldlink = (char *)statmalloc(strlen(tempcwd)+strlen(filename)+2);
   oldlink[0] = '\0';
   strcat(oldlink,tempcwd);
   strcat(oldlink,"/");
   strcat(oldlink,filename);
   
   freemalloc(tempcwd);
   
   /*   printf("Filename: %s\n",filename);
    printf("Oldlink: %s\n",oldlink); */
   
   MYcwd = MYgetcwd();
   newlink = (char *)statmalloc(strlen(MYcwd)+strlen(cwd)+strlen(filename)+2);   
   newlink[0] = '\0';
   strcat(newlink,MYcwd);
   strcat(newlink,cwd);
   strcat(newlink,"/");
   strcat(newlink,filename);
   freemalloc(MYcwd);
   
   while (!jump) {
      
      if ((ptr2 = strchr(ptr1,'/')) == NULL) {
         ptr2 = cwd+strlen(cwd);
         jump = 1;
      }
      
      if (sdlen > 0) {
         
         dirname = (char *)statmalloc((ptr2-ptr1)+1);
         dirname[0] = '\0';
         strncat(dirname,ptr1,ptr2-ptr1);
         
         if (mkdir(dirname,TDIRMODE) == -1 && errno != 17) {
            fprintf(stderr,"%s: trash bin: %s: %s\n",progname,dirname,strerror(errno));
            freemalloc(cwd);
            freemalloc(dirname);
            freemalloc(oldlink);
            freemalloc(newlink);
            if (fchdir(dest_fd) == -1) {
               fprintf(stderr,"%s: trash bin: %s\n",progname,strerror(errno));
               return(-1);
            }
            return(-1);
         }
         
         if (chdir(dirname) == -1) {
            fprintf(stderr,"%s: trash bin: %s: %s\n",progname,dirname,strerror(errno));
            freemalloc(cwd);
            freemalloc(dirname);
            freemalloc(oldlink);
            freemalloc(newlink);
            if (fchdir(dest_fd) == -1) {
               fprintf(stderr,"%s: trash bin: %s\n",progname,strerror(errno));
               return(-1);
            }
            return(-1);
         }
         
         freemalloc(dirname);         
      } else
          jump = 1;
      
      if (!jump)
          ptr1 = ptr2+1;      
      
   }
   
   freemalloc(cwd);
   
   lstat(oldlink,&flink);
   
   /* If a symlink, Create Appropriately */
   
   if (S_ISLNK(flink.st_mode)) {
      
      if ((linkbytes = readlink(oldlink,symbuf,MYPATH_MAX)) < 0) {
         fprintf(stderr,"%s: trash bin: %s: readlink: %s\n",progname,oldlink,strerror(errno));
         freemalloc(oldlink);
         freemalloc(newlink);
         return(-1);
      }
      
      symbuf[linkbytes] = '\0';
      
      remove(newlink);
      
      if (symlink(symbuf,newlink) == -1) {
         fprintf(stderr,"%s: trash bin: %s: symlink: %s\n",progname,newlink,strerror(errno));
         freemalloc(oldlink);
         freemalloc(newlink);
         return(-1);
      }
      
   } else if (ttype == 'S') {
      
      remove(newlink);
      
      if (link(oldlink,newlink) == -1) {
         fprintf(stderr,"%s: trash link: %s\n\toldpath: %s\n\tnewpath: %s\n",progname,strerror(errno),oldlink,newlink);
      }
      
   } else {
      
      if ((ifexist = open(newlink,O_RDONLY)) != -1) {
         close(ifexist);
         rmrec(newlink);
      }
      
      if (rename(oldlink,newlink) == -1) {
         fprintf(stderr,"%s: Trash Bin Dir: %s: %s\n",progname,newlink,strerror(errno));
         freemalloc(oldlink);
         freemalloc(newlink);
         return(-1);
      }
      
   }
   
   freemalloc(oldlink);
   freemalloc(newlink);
   
   if (fchdir(dest_fd) == -1) {
      fprintf(stderr,"%s: trash bin: chdir: %s\n",progname,strerror(errno));
      return(-1);
   }
   
   return(0);
}



syntax highlighted by Code2HTML, v. 0.9.1