diff options
author | Alexander Shishkin <virtuoso@slind.org> | 2010-10-20 13:22:24 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-10-20 13:22:58 +0200 |
commit | 5be79ff27a5852567a9bdec80d67b061ad828290 (patch) | |
tree | 6c3b1d7ee70394a36c0efdf7d3f3d12ba1e5b9ab | |
parent | bec588878b6d435c33d9b0aae6247715c259e3a4 (diff) | |
download | busybox-w32-5be79ff27a5852567a9bdec80d67b061ad828290.tar.gz busybox-w32-5be79ff27a5852567a9bdec80d67b061ad828290.tar.bz2 busybox-w32-5be79ff27a5852567a9bdec80d67b061ad828290.zip |
add-shell, remove-shell: new applets
function old new delta
add_remove_shell_main - 259 +259
packed_usage 27408 27438 +30
applet_names 2326 2349 +23
applet_main 1364 1372 +8
applet_nameofs 682 686 +4
run_applet_and_exit 700 703 +3
dont_add - 2 +2
applet_install_loc 171 172 +1
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 6/0 up/down: 330/0) Total: 330 bytes
Signed-off-by: Alexander Shishkin <virtuoso@slind.org>
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r-- | loginutils/add-remove-shell.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c new file mode 100644 index 000000000..986fe57c5 --- /dev/null +++ b/loginutils/add-remove-shell.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * add-shell and remove-shell implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation. All rights reserved. | ||
5 | * Written by Alexander Shishkin <virtuoso@slind.org> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see the LICENSE file in this source tree | ||
8 | * for details. | ||
9 | */ | ||
10 | |||
11 | //applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, add_shell )) | ||
12 | //applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, remove_shell)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_ADD_SHELL) += add-remove-shell.o | ||
15 | //kbuild:lib-$(CONFIG_REMOVE_SHELL) += add-remove-shell.o | ||
16 | |||
17 | //config:config ADD_SHELL | ||
18 | //config: bool "add-shell" | ||
19 | //config: default y if DESKTOP | ||
20 | //config: help | ||
21 | //config: Add shells to /etc/shells. | ||
22 | //config: | ||
23 | //config:config REMOVE_SHELL | ||
24 | //config: bool "remove-shell" | ||
25 | //config: default y if DESKTOP | ||
26 | //config: help | ||
27 | //config: Remove shells from /etc/shells. | ||
28 | |||
29 | //usage:#define add_shell_trivial_usage | ||
30 | //usage: "SHELL..." | ||
31 | //usage:#define add_shell_full_usage "\n\n" | ||
32 | //usage: "Add SHELLs to /etc/shells" | ||
33 | |||
34 | //usage:#define remove_shell_trivial_usage | ||
35 | //usage: "SHELL..." | ||
36 | //usage:#define remove_shell_full_usage "\n\n" | ||
37 | //usage: "Remove SHELLs from /etc/shells" | ||
38 | |||
39 | #include "libbb.h" | ||
40 | |||
41 | #define SHELLS_FILE "/etc/shells" | ||
42 | |||
43 | #define REMOVE_SHELL (ENABLE_REMOVE_SHELL && (!ENABLE_ADD_SHELL || applet_name[0] == 'r')) | ||
44 | #define ADD_SHELL (ENABLE_ADD_SHELL && (!ENABLE_REMOVE_SHELL || applet_name[0] == 'a')) | ||
45 | |||
46 | /* NB: we use the _address_, not the value, of this string | ||
47 | * as a "special value of pointer" in the code. | ||
48 | */ | ||
49 | static const char dont_add[] ALIGN1 = "\n"; | ||
50 | |||
51 | int add_remove_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
52 | int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | ||
53 | { | ||
54 | FILE *orig_fp; | ||
55 | char *orig_fn; | ||
56 | char *new_fn; | ||
57 | |||
58 | argv++; | ||
59 | |||
60 | orig_fn = xmalloc_follow_symlinks(SHELLS_FILE); | ||
61 | if (!orig_fn) | ||
62 | return EXIT_FAILURE; | ||
63 | orig_fp = fopen_for_read(orig_fn); | ||
64 | |||
65 | new_fn = xasprintf("%s.tmp", orig_fn); | ||
66 | xmove_fd(xopen(new_fn, O_WRONLY | O_CREAT | O_EXCL), STDOUT_FILENO); | ||
67 | |||
68 | /* TODO: | ||
69 | struct stat sb; | ||
70 | fstat(fileno(orig_fp), &sb); | ||
71 | xfchown(STDOUT_FILENO, sb.st_uid, sb.st_gid); | ||
72 | xfchmod(STDOUT_FILENO, sb.st_mode); | ||
73 | */ | ||
74 | |||
75 | if (orig_fp) { | ||
76 | /* Copy old file, possibly skipping removed shell names */ | ||
77 | char *line; | ||
78 | while ((line = xmalloc_fgetline(orig_fp)) != NULL) { | ||
79 | char **cpp = argv; | ||
80 | while (*cpp) { | ||
81 | if (strcmp(*cpp, line) == 0) { | ||
82 | /* Old file has this shell name */ | ||
83 | if (REMOVE_SHELL) { | ||
84 | /* we are remove-shell */ | ||
85 | /* delete this name by not copying it */ | ||
86 | goto next_line; | ||
87 | } | ||
88 | /* we are add-shell */ | ||
89 | /* mark this name as "do not add" */ | ||
90 | *cpp = (char*)dont_add; | ||
91 | } | ||
92 | cpp++; | ||
93 | } | ||
94 | /* copy shell name from old to new file */ | ||
95 | printf("%s\n", line); | ||
96 | next_line: | ||
97 | free(line); | ||
98 | } | ||
99 | if (ENABLE_FEATURE_CLEAN_UP) | ||
100 | fclose(orig_fp); | ||
101 | } | ||
102 | |||
103 | if (ADD_SHELL) { | ||
104 | char **cpp = argv; | ||
105 | while (*cpp) { | ||
106 | if (*cpp != dont_add) | ||
107 | printf("%s\n", *cpp); | ||
108 | cpp++; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | /* Ensure we wrote out everything */ | ||
113 | if (fclose(stdout) != 0) { | ||
114 | xunlink(new_fn); | ||
115 | bb_perror_msg_and_die("%s: write error", new_fn); | ||
116 | } | ||
117 | |||
118 | /* Small hole: if rename fails, /etc/shells.tmp is not removed */ | ||
119 | xrename(new_fn, orig_fn); | ||
120 | |||
121 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
122 | free(orig_fn); | ||
123 | free(new_fn); | ||
124 | } | ||
125 | |||
126 | return EXIT_SUCCESS; | ||
127 | } | ||