/*
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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() */
