[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 <[email protected]>
---
 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 <[email protected]>
+ *
+ * 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

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to