diff options
Diffstat (limited to '')
| -rw-r--r-- | doc/bus-broadcast.1 | 6 | ||||
| -rw-r--r-- | doc/bus-chgrp.1 | 1 | ||||
| -rw-r--r-- | doc/bus-chmod.1 | 1 | ||||
| -rw-r--r-- | doc/bus-chown.1 | 1 | ||||
| -rw-r--r-- | doc/bus-create.1 | 6 | ||||
| -rw-r--r-- | doc/bus-listen.1 | 3 | ||||
| -rw-r--r-- | doc/bus-remove.1 | 1 | ||||
| -rw-r--r-- | doc/bus-wait.1 | 1 | ||||
| -rw-r--r-- | src/cmdline.c | 119 | 
9 files changed, 98 insertions, 41 deletions
| diff --git a/doc/bus-broadcast.1 b/doc/bus-broadcast.1 index d80c6d2..5a4a7a3 100644 --- a/doc/bus-broadcast.1 +++ b/doc/bus-broadcast.1 @@ -3,10 +3,16 @@  bus broadcast - Broadcast a message on a bus  .SH SYNOPSIS  .B bus broadcast +.IR [options] +[--]  .IR pathname  .IR message  .SH DESCRIPTION  Broadcast \fImessage\fP on the bus associated with \fIpathname\fP. +.SH OPTIONS +.TP +.B \-n +Fail if another process is attempting to broadcast on the bus.  .SH EXIT STATUS  .TP  0 diff --git a/doc/bus-chgrp.1 b/doc/bus-chgrp.1 index cb59916..49f5642 100644 --- a/doc/bus-chgrp.1 +++ b/doc/bus-chgrp.1 @@ -3,6 +3,7 @@  bus chgrp - Change group ownership of a bus  .SH SYNOPSIS  .B bus chgrp +[--]  .IR group  .IR pathname  .SH DESCRIPTION diff --git a/doc/bus-chmod.1 b/doc/bus-chmod.1 index f50688c..24cdac9 100644 --- a/doc/bus-chmod.1 +++ b/doc/bus-chmod.1 @@ -3,6 +3,7 @@  bus chmod - Change permissions on a bus  .SH SYNOPSIS  .B bus chmod +[--]  .IR permissions  .IR pathname  .SH DESCRIPTION diff --git a/doc/bus-chown.1 b/doc/bus-chown.1 index 64aa7d2..a9c09ff 100644 --- a/doc/bus-chown.1 +++ b/doc/bus-chown.1 @@ -3,6 +3,7 @@  bus chown - Change ownership of a bus  .SH SYNOPSIS  .B bus chown +[--]  .IR owner[:group]  .IR pathname  .SH DESCRIPTION diff --git a/doc/bus-create.1 b/doc/bus-create.1 index 8282413..f50ad97 100644 --- a/doc/bus-create.1 +++ b/doc/bus-create.1 @@ -3,11 +3,17 @@  bus create - Create a bus  .SH SYNOPSIS  .B bus create +.IR [options] +[--]  .IR [pathname]  .SH DESCRIPTION  Create a bus with an associated \fIpathname\fP. If \fIpathname\fP, a  random pathname in \fI$XDG_RUNTIME_DIR/bus\fP will be created and  printed to stdout. +.SH OPTIONS +.TP +.B \-x +Fail if the \fIpathname\fP already exists.  .SH EXIT STATUS  .TP  0 diff --git a/doc/bus-listen.1 b/doc/bus-listen.1 index 0d5b9ba..0f56398 100644 --- a/doc/bus-listen.1 +++ b/doc/bus-listen.1 @@ -2,7 +2,8 @@  .SH NAME  bus listen - Listen for new messages on a bus  .SH SYNOPSIS -.B bus wait +.B bus listen +[--]  .IR pathname  .IR command  .SH DESCRIPTION diff --git a/doc/bus-remove.1 b/doc/bus-remove.1 index 1979629..1b14d50 100644 --- a/doc/bus-remove.1 +++ b/doc/bus-remove.1 @@ -3,6 +3,7 @@  bus remove - Remove a bus  .SH SYNOPSIS  .B bus remove +[--]  .IR pathname  .SH DESCRIPTION  Remove the bus associated with \fIpathname\fP. diff --git a/doc/bus-wait.1 b/doc/bus-wait.1 index 5fec137..c9add51 100644 --- a/doc/bus-wait.1 +++ b/doc/bus-wait.1 @@ -3,6 +3,7 @@  bus wait - Listen for a new message on a bus  .SH SYNOPSIS  .B bus wait +[--]  .IR pathname  .IR command  .SH DESCRIPTION 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; +	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; + +	/* 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; | 
