/* vi: set sw=4 ts=4: */
/*
 * ipcrm.c - utility to allow removal of IPC objects and data structures.
 *
 * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
 * Adapted for busybox from util-linux-2.12a.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include "libbb.h"

/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun {
	int val;
	struct semid_ds *buf;
	unsigned short int *array;
	struct seminfo *__buf;
};
#endif

#ifndef CONFIG_IPCRM_DROP_LEGACY

typedef enum type_id {
	SHM,
	SEM,
	MSG
} type_id;

static int remove_ids(type_id type, int argc, char **argv)
{
	unsigned long id;
	int ret = 0;		/* silence gcc */
	int nb_errors = 0;
	union semun arg;

	arg.val = 0;

	while (argc) {
		id = bb_strtoul(argv[0], NULL, 10);
		if (errno || id > INT_MAX) {
			bb_error_msg("invalid id: %s", argv[0]);
			nb_errors++;
		} else {
			if (type == SEM)
				ret = semctl(id, 0, IPC_RMID, arg);
			else if (type == MSG)
				ret = msgctl(id, IPC_RMID, NULL);
			else if (type ==  SHM)
				ret = shmctl(id, IPC_RMID, NULL);

			if (ret) {
				bb_perror_msg("cannot remove id %s", argv[0]);
				nb_errors++;
			}
		}
		argc--;
		argv++;
	}

	return nb_errors;
}
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */


int ipcrm_main(int argc, char **argv);
int ipcrm_main(int argc, char **argv)
{
	int c;
	int error = 0;

	/* if the command is executed without parameters, do nothing */
	if (argc == 1)
		return 0;
#ifndef CONFIG_IPCRM_DROP_LEGACY
	/* check to see if the command is being invoked in the old way if so
	   then run the old code. Valid commands are msg, shm, sem. */
	{
		type_id what = 0; /* silence gcc */
		char w;

		w=argv[1][0];
		if ( ((w == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
		       || (argv[1][0] == 's'
		           && ((w=argv[1][1]) == 'h' || w == 'e')
		           && argv[1][2] == 'm')
		     ) && argv[1][3] == '\0'
		) {

			if (argc < 3)
				bb_show_usage();

			if (w == 'h')
				what = SHM;
			else if (w == 'm')
				what = MSG;
			else if (w == 'e')
				what = SEM;

			if (remove_ids(what, argc-2, &argv[2]))
				fflush_stdout_and_exit(1);
			printf("resource(s) deleted\n");
			return 0;
		}
	}
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */

	/* process new syntax to conform with SYSV ipcrm */
	while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
		int result;
		int id = 0;
		int iskey = (isupper)(c);

		/* needed to delete semaphores */
		union semun arg;

		arg.val = 0;

		if ((c == '?') || (c == 'h')) {
			bb_show_usage();
		}

		/* we don't need case information any more */
		c = tolower(c);

		/* make sure the option is in range: allowed are q, m, s */
		if (c != 'q' && c != 'm' && c != 's') {
			bb_show_usage();
		}

		if (iskey) {
			/* keys are in hex or decimal */
			key_t key = xstrtoul(optarg, 0);

			if (key == IPC_PRIVATE) {
				error++;
				bb_error_msg("illegal key (%s)", optarg);
				continue;
			}

			/* convert key to id */
			id = ((c == 'q') ? msgget(key, 0) :
				  (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));

			if (id < 0) {
				const char *errmsg;

				error++;
				switch (errno) {
				case EACCES:
					errmsg = "permission denied for";
					break;
				case EIDRM:
					errmsg = "already removed";
					break;
				case ENOENT:
					errmsg = "invalid";
					break;
				default:
					errmsg = "unknown error in";
					break;
				}
				bb_error_msg("%s %s (%s)", errmsg, "key", optarg);
				continue;
			}
		} else {
			/* ids are in decimal */
			id = xatoul(optarg);
		}

		result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
				  (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
				  semctl(id, 0, IPC_RMID, arg));

		if (result) {
			const char *errmsg;
			const char *const what = iskey ? "key" : "id";

			error++;
			switch (errno) {
			case EACCES:
			case EPERM:
				errmsg = "permission denied for";
				break;
			case EINVAL:
				errmsg = "invalid";
				break;
			case EIDRM:
				errmsg = "already removed";
				break;
			default:
				errmsg = "unknown error in";
				break;
			}
			bb_error_msg("%s %s (%s)", errmsg, what, optarg);
			continue;
		}
	}

	/* print usage if we still have some arguments left over */
	if (optind != argc) {
		bb_show_usage();
	}

	/* exit value reflects the number of errors encountered */
	return error;
}
