aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cmdline.c119
1 files changed, 79 insertions, 40 deletions
diff --git a/src/cmdline.c b/src/cmdline.c
index 69adae2..97da729 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -292,14 +292,14 @@ parse_owner(char *str, uid_t *uid, gid_t *gid)
*
* @param argc The number of elements in `argv`
* @param argv The command. Valid commands:
- * <argv0> create [<path>] # create a bus
- * <argv0> remove <path> # remove a bus
- * <argv0> listen <path> <command> # listen for new messages
- * <argv0> wait <path> <command> # listen for one new message
- * <argv0> broadcast <path> <message> # broadcast a message
- * <argv0> chmod <mode> <path> # change permissions
- * <argv0> chown <owner>[:<group>] <path> # change ownership
- * <argv0> chgrp <group> <path> # change group
+ * <argv0> create [-x] [--] [<path>] # create a bus
+ * <argv0> remove [--] <path> # remove a bus
+ * <argv0> listen [--] <path> <command> # listen for new messages
+ * <argv0> wait [--] <path> <command> # listen for one new message
+ * <argv0> broadcast [-n] [--] <path> <message> # broadcast a message
+ * <argv0> chmod [--] <mode> <path> # change permissions
+ * <argv0> chown [--] <owner>[:<group>] <path> # change ownership
+ * <argv0> chgrp [--] <group> <path> # change group
* <command> will be spawned with $arg set to the message
* @return 0 on sucess, 1 on error, 2 on invalid command
*/
@@ -312,69 +312,108 @@ main(int argc, char *argv[])
uid_t uid;
gid_t gid;
mode_t mode_andnot, mode_or;
+ int opt_x = 0, opt_n = 0;
+ const char *arg;
+ char **nonoptv = alloca(argc * sizeof(char*));
+ int nonoptc = 0;
+
+ argv0 = *argv++;
+ argc--;
+
+ /* Parse arguments. */
+ while (argc) {
+ if (!strcmp(*argv, "--")) {
+ argv++;
+ argc--;
+ break;
+ } else if (**argv == '-') {
+ arg = *argv++;
+ argc--;
+ for (arg++; *arg; arg++) {
+ if (*arg == 'x')
+ opt_x = 1;
+ else if (*arg == 'n')
+ opt_n = 1;
+ else
+ return -2;
+ }
+ } else {
+ *nonoptv++ = *argv++;
+ nonoptc++;
+ argc--;
+ }
+ }
+ while (argc) {
+ *nonoptv++ = *argv++;
+ nonoptc++;
+ argc--;
+ }
+ nonoptv -= nonoptc;
- argv0 = *argv;
+ /* Check options. */
+ if (opt_x && strcmp(nonoptv[0], "create") && (nonoptc != 2))
+ return 2;
+ if (opt_n && strcmp(nonoptv[0], "broadcast") && (nonoptc != 3))
+ return 2;
/* Create a new bus with selected name. */
- if ((argc == 3) && !strcmp(argv[1], "create")) {
- t(bus_create(argv[2], 0, NULL));
- /* TODO add -x */
+ if ((nonoptc == 2) && !strcmp(nonoptv[0], "create")) {
+ t(bus_create(nonoptv[1], opt_x * BUS_EXCL, NULL));
/* Create a new bus with random name. */
- } else if ((argc == 2) && !strcmp(argv[1], "create")) {
+ } else if ((nonoptc == 1) && !strcmp(nonoptv[0], "create")) {
t(bus_create(NULL, 0, &file));
printf("%s\n", file);
free(file);
/* Remove a bus. */
- } else if ((argc == 3) && !strcmp(argv[1], "remove")) {
- t(bus_unlink(argv[2]));
+ } else if ((nonoptc == 2) && !strcmp(nonoptv[0], "remove")) {
+ t(bus_unlink(nonoptv[1]));
/* Listen on a bus in a loop. */
- } else if ((argc == 4) && !strcmp(argv[1], "listen")) {
- command = argv[3];
- t(bus_open(&bus, argv[2], BUS_RDONLY));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "listen")) {
+ command = nonoptv[2];
+ t(bus_open(&bus, nonoptv[1], BUS_RDONLY));
t(bus_read(&bus, spawn_continue, NULL));
t(bus_close(&bus));
/* Listen on a bus for one message. */
- } else if ((argc == 4) && !strcmp(argv[1], "wait")) {
- command = argv[3];
- t(bus_open(&bus, argv[2], BUS_RDONLY));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "wait")) {
+ command = nonoptv[2];
+ t(bus_open(&bus, nonoptv[1], BUS_RDONLY));
t(bus_read(&bus, spawn_break, NULL));
t(bus_close(&bus));
/* Broadcast a message on a bus. */
- } else if ((argc == 4) && !strcmp(argv[1], "broadcast")) {
- t(bus_open(&bus, argv[2], BUS_WRONLY));
- t(bus_write(&bus, argv[3], 0));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "broadcast")) {
+ t(bus_open(&bus, nonoptv[1], BUS_WRONLY));
+ t(bus_write(&bus, nonoptv[2], opt_n * BUS_NOWAIT));
t(bus_close(&bus));
- /* TODO add -n */
/* Change permissions. */
- } else if ((argc == 4) && !strcmp(argv[1], "chmod")) {
- t(parse_mode(argv[2], &mode_andnot, &mode_or));
- t(stat(argv[3], &attr));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "chmod")) {
+ t(parse_mode(nonoptv[1], &mode_andnot, &mode_or));
+ t(stat(nonoptv[2], &attr));
attr.st_mode &= ~mode_andnot;
attr.st_mode |= mode_or;
- t(bus_chmod(argv[3], attr.st_mode));
+ t(bus_chmod(nonoptv[2], attr.st_mode));
/* Change ownership. */
- } else if ((argc == 4) && !strcmp(argv[1], "chown")) {
- if (strchr(argv[2], ':')) {
- t(parse_owner(argv[2], &uid, &gid));
- t(bus_chown(argv[3], uid, gid));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "chown")) {
+ if (strchr(nonoptv[1], ':')) {
+ t(parse_owner(nonoptv[1], &uid, &gid));
+ t(bus_chown(nonoptv[2], uid, gid));
} else {
- t(parse_owner(argv[2], &uid, NULL));
- t(stat(argv[3], &attr));
- t(bus_chown(argv[3], uid, attr.st_gid));
+ t(parse_owner(nonoptv[1], &uid, NULL));
+ t(stat(nonoptv[2], &attr));
+ t(bus_chown(nonoptv[2], uid, attr.st_gid));
}
/* Change group. */
- } else if ((argc == 4) && !strcmp(argv[1], "chgrp")) {
- t(parse_owner(argv[2], NULL, &gid));
- t(stat(argv[3], &attr));
- t(bus_chown(argv[3], attr.st_uid, gid));
+ } else if ((nonoptc == 3) && !strcmp(nonoptv[0], "chgrp")) {
+ t(parse_owner(nonoptv[1], NULL, &gid));
+ t(stat(nonoptv[2], &attr));
+ t(bus_chown(nonoptv[2], attr.st_uid, gid));
} else
return 2;