summaryrefslogtreecommitdiff
path: root/ltp_framework/lib/rmobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltp_framework/lib/rmobj.c')
-rw-r--r--ltp_framework/lib/rmobj.c211
1 files changed, 211 insertions, 0 deletions
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 <errno.h> /* for errno */
+#include <stdio.h> /* for NULL */
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for string function */
+#include <limits.h> /* for PATH_MAX */
+#include <sys/types.h> /* for opendir(), readdir(), closedir(), stat() */
+#include <sys/stat.h> /* for [l]stat() */
+#include <dirent.h> /* for opendir(), readdir(), closedir() */
+#include <unistd.h> /* 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