From 01c165cd1b2ac601d5ae73d3cb5e82ccdd94ac94 Mon Sep 17 00:00:00 2001 From: Le Chi Thu Date: Tue, 3 Apr 2012 01:23:00 +0200 Subject: Initial commit --- ltp_framework/lib/rmobj.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 ltp_framework/lib/rmobj.c (limited to 'ltp_framework/lib/rmobj.c') diff --git a/ltp_framework/lib/rmobj.c b/ltp_framework/lib/rmobj.c new file mode 100644 index 0000000..1ac9ee3 --- /dev/null +++ b/ltp_framework/lib/rmobj.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ + */ + +/* $Id: rmobj.c,v 1.5 2009/07/20 10:59:32 vapier Exp $ */ + +/********************************************************** + * + * OS Testing - Silicon Graphics, Inc. + * + * FUNCTION NAME : rmobj() + * + * FUNCTION TITLE : Remove an object + * + * SYNOPSIS: + * int rmobj(char *obj, char **errmsg) + * + * AUTHOR : Kent Rogers + * + * INITIAL RELEASE : UNICOS 7.0 + * + * USER DESCRIPTION + * This routine will remove the specified object. If the specified + * object is a directory, it will recursively remove the directory + * and everything underneath it. It assumes that it has privilege + * to remove everything that it tries to remove. If rmobj() encounters + * any problems, and errmsg is not NULL, errmsg is set to point to a + * string explaining the error. + * + * DETAILED DESCRIPTION + * Allocate space for the directory and its contents + * Open the directory to get access to what is in it + * Loop through the objects in the directory: + * If the object is not "." or "..": + * Determine the file type by calling lstat() + * If the object is not a directory: + * Remove the object with unlink() + * Else: + * Call rmobj(object) to remove the object's contents + * Determine the link count on object by calling lstat() + * If the link count >= 3: + * Remove the directory with unlink() + * Else + * Remove the directory with rmdir() + * Close the directory and free the pointers + * + * RETURN VALUE + * If there are any problems, rmobj() will set errmsg (if it was not + * NULL) and return -1. Otherwise it will return 0. + * + ************************************************************/ +#include /* for errno */ +#include /* for NULL */ +#include /* for malloc() */ +#include /* for string function */ +#include /* for PATH_MAX */ +#include /* for opendir(), readdir(), closedir(), stat() */ +#include /* for [l]stat() */ +#include /* for opendir(), readdir(), closedir() */ +#include /* for rmdir(), unlink() */ +#include "rmobj.h" + +#define SYSERR strerror(errno) + +int +rmobj(char *obj, char **errmsg) +{ + int ret_val = 0; /* return value from this routine */ + DIR *dir; /* pointer to a directory */ + struct dirent *dir_ent; /* pointer to directory entries */ + char dirobj[PATH_MAX]; /* object inside directory to modify */ + struct stat statbuf; /* used to hold stat information */ + static char err_msg[1024]; /* error message */ + + /* Determine the file type */ + if (lstat(obj, &statbuf) < 0) { + if (errmsg != NULL) { + sprintf(err_msg, "lstat(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } + + /* Take appropriate action, depending on the file type */ + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { + /* object is a directory */ + + /* Do NOT perform the request if the directory is "/" */ + if (!strcmp(obj, "/")) { + if (errmsg != NULL) { + sprintf(err_msg, "Cannot remove /"); + *errmsg = err_msg; + } + return -1; + } + + /* Open the directory to get access to what is in it */ + if ((dir = opendir(obj)) == NULL) { + if (rmdir(obj) != 0) { + if (errmsg != NULL) { + sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } else { + return 0; + } + } + + /* Loop through the entries in the directory, removing each one */ + for (dir_ent = (struct dirent *)readdir(dir); + dir_ent != NULL; + dir_ent = (struct dirent *)readdir(dir)) { + + /* Don't remove "." or ".." */ + if (!strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, "..")) + continue; + + /* Recursively call this routine to remove the current entry */ + sprintf(dirobj, "%s/%s", obj, dir_ent->d_name); + if (rmobj(dirobj, errmsg) != 0) + ret_val = -1; + } + + /* Close the directory */ + closedir(dir); + + /* If there were problems removing an entry, don't attempt to + remove the directory itself */ + if (ret_val == -1) + return -1; + + /* Get the link count, now that all the entries have been removed */ + if (lstat(obj, &statbuf) < 0) { + if (errmsg != NULL) { + sprintf(err_msg, "lstat(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } + + /* Remove the directory itself */ + if (statbuf.st_nlink >= 3) { + /* The directory is linked; unlink() must be used */ + if (unlink(obj) < 0) { + if (errmsg != NULL) { + sprintf(err_msg, "unlink(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } + } else { + /* The directory is not linked; remove() can be used */ + if (remove(obj) < 0) { + if (errmsg != NULL) { + sprintf(err_msg, "remove(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } + } + } else { + /* object is not a directory; just use unlink() */ + if (unlink(obj) < 0) { + if (errmsg != NULL) { + sprintf(err_msg, "unlink(%s) failed; errno=%d: %s", + obj, errno, SYSERR); + *errmsg = err_msg; + } + return -1; + } + } /* if obj is a directory */ + + /* + * Everything must have went ok. + */ + return 0; +} /* rmobj() */ \ No newline at end of file -- cgit v1.2.3