aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shishkin <virtuoso@slind.org>2010-10-20 13:22:24 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-10-20 13:22:58 +0200
commit5be79ff27a5852567a9bdec80d67b061ad828290 (patch)
tree6c3b1d7ee70394a36c0efdf7d3f3d12ba1e5b9ab
parentbec588878b6d435c33d9b0aae6247715c259e3a4 (diff)
downloadbusybox-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.c127
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 */
49static const char dont_add[] ALIGN1 = "\n";
50
51int add_remove_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
52int 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}