tls: in AES-GCM decoding, avoid memmove
[oweals/busybox.git] / util-linux / ipcrm.c
index 886c2efbd9d5987356495dd64ef720afc1c5c440..a93ceee11879a688a5a3f21aa6bc92efe54d8ef9 100644 (file)
@@ -5,10 +5,21 @@
  * 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.
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
+//config:config IPCRM
+//config:      bool "ipcrm (2.9 kb)"
+//config:      default y
+//config:      help
+//config:      The ipcrm utility allows the removal of System V interprocess
+//config:      communication (IPC) objects and the associated data structures
+//config:      from the system.
 
-#include "busybox.h"
+//applet:IF_IPCRM(APPLET_NOEXEC(ipcrm, ipcrm, BB_DIR_USR_BIN, BB_SUID_DROP, ipcrm))
+
+//kbuild:lib-$(CONFIG_IPCRM) += ipcrm.o
+
+#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/msg.h>
 #include <sys/sem.h>
 
-#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+#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;
+       unsigned short *array;
        struct seminfo *__buf;
 };
 #endif
 
-#ifndef CONFIG_IPCRM_DROP_LEGACY
+#define IPCRM_LEGACY 1
+
+
+#if IPCRM_LEGACY
 
 typedef enum type_id {
        SHM,
@@ -37,21 +51,21 @@ typedef enum type_id {
        MSG
 } type_id;
 
-static int remove_ids(type_id type, int argc, char **argv)
+static int remove_ids(type_id type, char **argv)
 {
        unsigned long id;
-       int ret = 0;            /* silence gcc */
        int nb_errors = 0;
        union semun arg;
 
        arg.val = 0;
 
-       while (argc) {
+       while (argv[0]) {
                id = bb_strtoul(argv[0], NULL, 10);
                if (errno || id > INT_MAX) {
                        bb_error_msg("invalid id: %s", argv[0]);
                        nb_errors++;
                } else {
+                       int ret = 0;
                        if (type == SEM)
                                ret = semctl(id, 0, IPC_RMID, arg);
                        else if (type == MSG)
@@ -60,19 +74,27 @@ static int remove_ids(type_id type, int argc, char **argv)
                                ret = shmctl(id, IPC_RMID, NULL);
 
                        if (ret) {
-                               bb_perror_msg("cannot remove id %s", argv[0]);
+                               bb_perror_msg("can't remove id %s", argv[0]);
                                nb_errors++;
                        }
                }
-               argc--;
                argv++;
        }
 
        return nb_errors;
 }
-#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
-
-
+#endif /* IPCRM_LEGACY */
+
+//usage:#define ipcrm_trivial_usage
+//usage:       "[-MQS key] [-mqs id]"
+//usage:#define ipcrm_full_usage "\n\n"
+//usage:       "Upper-case options MQS remove an object by shmkey value.\n"
+//usage:       "Lower-case options remove an object by shmid value.\n"
+//usage:     "\n       -mM     Remove memory segment after last detach"
+//usage:     "\n       -qQ     Remove message queue"
+//usage:     "\n       -sS     Remove semaphore"
+
+int ipcrm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int ipcrm_main(int argc, char **argv)
 {
        int c;
@@ -81,21 +103,20 @@ int ipcrm_main(int argc, char **argv)
        /* if the command is executed without parameters, do nothing */
        if (argc == 1)
                return 0;
-#ifndef CONFIG_IPCRM_DROP_LEGACY
+#if IPCRM_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];
+               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')
+                          && ((w = argv[1][1]) == 'h' || w == 'e')
                           && argv[1][2] == 'm')
                     ) && argv[1][3] == '\0'
                ) {
-
                        if (argc < 3)
                                bb_show_usage();
 
@@ -106,37 +127,29 @@ int ipcrm_main(int argc, char **argv)
                        else if (w == 'e')
                                what = SEM;
 
-                       if (remove_ids(what, argc-2, &argv[2]))
-                               fflush_stdout_and_exit(1);
-                       printf("resource(s) deleted\n");
+                       if (remove_ids(what, &argv[2]))
+                               fflush_stdout_and_exit(EXIT_FAILURE);
+                       puts("resource(s) deleted");
                        return 0;
                }
        }
-#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
+#endif /* IPCRM_LEGACY */
 
        /* process new syntax to conform with SYSV ipcrm */
-       while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
+       while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
                int result;
-               int id = 0;
-               int iskey = (isupper)(c);
-
+               int id;
+               int iskey;
                /* needed to delete semaphores */
                union semun arg;
 
-               arg.val = 0;
-
-               if ((c == '?') || (c == 'h')) {
+               if (c == '?') /* option not in the string */
                        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();
-               }
+               id = 0;
+               arg.val = 0;
 
+               iskey = !(c & 0x20); /* uppercase? */
                if (iskey) {
                        /* keys are in hex or decimal */
                        key_t key = xstrtoul(optarg, 0);
@@ -147,13 +160,13 @@ int ipcrm_main(int argc, char **argv)
                                continue;
                        }
 
+                       c |= 0x20; /* lowercase. c is 'q', 'm' or 's' now */
                        /* convert key to id */
                        id = ((c == 'q') ? msgget(key, 0) :
-                                 (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
+                               (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
 
                        if (id < 0) {
                                const char *errmsg;
-                               const char *const what = "key";
 
                                error++;
                                switch (errno) {
@@ -170,7 +183,7 @@ int ipcrm_main(int argc, char **argv)
                                        errmsg = "unknown error in";
                                        break;
                                }
-                               bb_error_msg("%s %s (%s)",  errmsg, what, optarg);
+                               bb_error_msg("%s %s (%s)", errmsg, "key", optarg);
                                continue;
                        }
                } else {
@@ -179,8 +192,8 @@ int ipcrm_main(int argc, char **argv)
                }
 
                result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
-                                 (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
-                                 semctl(id, 0, IPC_RMID, arg));
+                               (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
+                               semctl(id, 0, IPC_RMID, arg));
 
                if (result) {
                        const char *errmsg;