/*****************************************************************************
* Backup Copy *
* Programmed by: Kevin Lindsay *
* Copyright (c) 1998 NetNation Communications Inc *
* ***************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include "statmalloc.h"
#ifdef BSD
#endif
/* Amount to increase buffer size by in each try. */
#define PATH_INCR 32
/* Globals */
int dirpos = 1;
ino_t root_inode = 0;
dev_t root_dev = 0;
int counter=0;
/* Return the current directory, newly allocated, arbitrarily long.
* Return NULL and set errno on error. */
char *
MYgetcwd ()
{
char *cwd;
char *ret;
unsigned path_max;
errno = 0;
path_max = (unsigned) MYPATH_MAX;
path_max += 2; /* The getcwd docs say to do this. */
cwd = (char *)statmalloc(path_max);
errno = 0;
while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE) {
path_max += PATH_INCR;
cwd = (char *)realloc(cwd, path_max);
errno = 0;
}
if (ret == NULL){
int save_errno = errno;
freemalloc(cwd);
errno = save_errno;
return NULL;
}
return cwd;
}
/* Unlink all files in current directory. If a non empty Dir is found, return dirname */
char *
unlink_dir(char *dirname)
{
DIR *dir_contents;
struct dirent *filename = NULL;
int check = 0;
counter = 0;
if ((dir_contents = opendir(".")) == NULL) {
fprintf(stderr,"%s: %s\n",dirname,strerror(errno));
return(NULL);
}
if ((filename = readdir(dir_contents)) == NULL) {
return(NULL);
}
seekdir(dir_contents,telldir(dir_contents)+1);
while (readdir(dir_contents) != NULL) {
counter=1;
check = 1;
// if (VERBOSE)
// printf("rmfile: %s/%s\n",MYgetcwd(),filename->d_name);
if (unlink(filename->d_name) == -1) {
if (errno == EISDIR || errno == EPERM) {
if (rmdir(filename->d_name) == -1) {
if (errno == ENOTEMPTY) {
closedir(dir_contents);
dirpos++;
return(filename->d_name);
} else {
closedir(dir_contents);
fprintf(stderr,"%s/%s: %s",dirname,filename->d_name,strerror(errno));
return(NULL);
}
}
} else {
closedir(dir_contents);
fprintf(stderr,"%s/%s: %s",dirname,filename->d_name,strerror(errno));
return(NULL);
}
}
seekdir(dir_contents,telldir(dir_contents));
}
if (!check) return(NULL);
closedir(dir_contents);
dirpos--;
return ("..");
}
/* Recursively Remove a Directory */
int
rmrec(char *dirname)
{
char *tempname;
struct stat root_fs;
char *rootdir = NULL;
char *MYcwd=NULL;
tempname = (char *)statmalloc(strlen(dirname)+1);
tempname[0] = '\0';
strcat(tempname,dirname);
if (chdir(dirname) != 0) {
dirname = NULL;
}
if (dirname != NULL && chdir("..") != 0) {
dirname = NULL;
}
else {
lstat(".",&root_fs);
root_inode = root_fs.st_ino;
root_dev = root_fs.st_dev;
MYcwd = MYgetcwd();
rootdir = (char *)statmalloc(strlen(MYcwd)+1);
rootdir[0] = '\0';
strcat(rootdir,MYcwd);
}
if (dirname != NULL && chdir(dirname) != 0) {
dirname = NULL;
}
while (dirname != NULL) {
dirname = unlink_dir(dirname);
if (chdir(dirname) != 0)
dirname = NULL;
freemalloc(MYcwd);
MYcwd = MYgetcwd();
if (strcmp(rootdir,MYcwd) == 0)
dirname = NULL;
if (dirname != NULL && strcmp(dirname,"..") == 0) {
lstat(".",&root_fs);
if (root_inode == root_fs.st_ino && root_dev == root_fs.st_dev)
dirname = NULL;
}
}
if (counter == 0)
chdir("..");
rmdir(tempname);
freemalloc(rootdir);
freemalloc(tempname);
freemalloc(MYcwd);
return(0);
}
syntax highlighted by Code2HTML, v. 0.9.1