[PATCH] add-shell, remove-shell: new applets

Alexander Shishkin virtuoso at slind.org
Tue Oct 19 20:33:49 UTC 2010


[Sorry, the previous mail seems to have been eaten by the smarthost,
apologies if it comes twice.]

function                                             old     new   delta
add_shell_main                                         -     459    +459
.rodata                                            50375   50495    +120
chomp                                                  -      24     +24
applet_names                                         920     943     +23
packed_usage                                        1640    1661     +21
applet_main                                         1232    1248     +16
applet_nameofs                                       308     312      +4
------------------------------------------------------------------------------
(add/remove: 4/0 grow/shrink: 5/0 up/down: 667/0)             Total: 667 bytes

Signed-off-by: Alexander Shishkin <virtuoso at slind.org>
---
 debianutils/add-remove-shell.c |  109 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 109 insertions(+), 0 deletions(-)
 create mode 100644 debianutils/add-remove-shell.c

diff --git a/debianutils/add-remove-shell.c b/debianutils/add-remove-shell.c
new file mode 100644
index 0000000..a6b265f
--- /dev/null
+++ b/debianutils/add-remove-shell.c
@@ -0,0 +1,109 @@
+/*
+ * add-shell and remove-shell implementation for busybox
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ * Written by Alexander Shishkin <virtuoso at slind.org>
+ *
+ * Licensed under GPLv2 or later, see the LICENSE file in this source tree
+ * for details.
+ */
+
+//applet:IF_ADD_REMOVE_SHELL(APPLET_ODDNAME(add-shell, add_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, add_shell))
+//applet:IF_ADD_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, remove_shell))
+//kbuild:lib-$(CONFIG_ADD_REMOVE_SHELL)     += add-remove-shell.o
+
+//config:config ADD_REMOVE_SHELL
+//config:       bool "add-shell / remove-shell"
+//config:       default y
+//config:       help
+//config:         Add/remove shells to/from /etc/shells.
+
+//usage:#define add_shell_trivial_usage
+//usage:       "shellname [shellname...]"
+//usage:#define add_shell_full_usage "\n\n"
+//usage:       "Add shells to the list of valid login shells\n"
+
+//usage:#define remove_shell_trivial_usage
+//usage:       "shellname [shellname...]"
+//usage:#define remove_shell_full_usage "\n\n"
+//usage:       "Remove shells to the list of valid login shells\n"
+
+#include "libbb.h"
+
+#define SHELLS_FILE	"/etc/shells"
+#define TMP_SFX		".tmp"
+
+static int update_shells(llist_t *shell_list, int add)
+{
+	FILE *orig, *new;
+	struct flock lock;
+	const char *orig_fn = SHELLS_FILE;
+	const char *tmp_fn = SHELLS_FILE TMP_SFX;
+
+	orig = fopen(orig_fn, "r+");
+	new = xfopen_for_write(tmp_fn);
+
+	/* if shells file exists, read it */
+	if (orig) {
+		lock.l_type = F_WRLCK;
+		lock.l_whence = SEEK_SET;
+		lock.l_start = 0;
+		lock.l_len = 0;
+		if (fcntl(fileno(orig), F_SETLK, &lock) < 0)
+			bb_perror_msg("warning: can't lock '%s'", orig_fn);
+		lock.l_type = F_UNLCK;
+
+		while (!feof(orig)) {
+			char *line;
+			llist_t *ours;
+
+			line = xmalloc_fgetline(orig);
+			if (!line)
+				break;
+
+			chomp(line);
+
+			/* if it's on the list and we're add-shell, remove it */
+			ours = llist_find_str(shell_list, line);
+			if (ours && add)
+				llist_unlink(&shell_list, ours);
+
+			/* skip if we're remove-shell and it's on the list */
+			if (add || !ours)
+				fprintf(new, "%s\n", line);
+
+			free(line);
+		}
+	}
+
+	/* append the what's left on the list */
+	if (add) {
+		char *line;
+
+		while ((line = llist_pop(&shell_list)))
+			fprintf(new, "%s\n", line);
+	}
+	fclose(new);
+
+	if (orig) {
+		fcntl(fileno(orig), F_SETLK, &lock);
+		fclose(orig);
+	}
+
+	xrename(tmp_fn, orig_fn);
+
+	return EXIT_SUCCESS;
+}
+
+int add_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int add_shell_main(int argc UNUSED_PARAM, char **argv)
+{
+	llist_t *shell_list = NULL;
+
+	/* there is nothing on the command line but the list of shells */
+	(void)*argv++;
+	while (*argv)
+		llist_add_to_end(&shell_list, *argv++);
+
+	return update_shells(shell_list, applet_name[0] == 'a');
+}
-- 
1.7.2.1.45.gb66c2



More information about the busybox mailing list