aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 00:54:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 00:54:59 +0000
commitc9bb67787a0d48af33045a2d813faf44ed5d59b4 (patch)
tree82508111fa3dc475a52260b1096353b6bf5782d2
parentbf11e8942d39d9445f1f6cfb6716f58b4d8189d5 (diff)
downloadbusybox-w32-c9bb67787a0d48af33045a2d813faf44ed5d59b4.tar.gz
busybox-w32-c9bb67787a0d48af33045a2d813faf44ed5d59b4.tar.bz2
busybox-w32-c9bb67787a0d48af33045a2d813faf44ed5d59b4.zip
deluser: size reduction by 60 bytes.
patch from Tito <farmatito@tiscali.it>
-rw-r--r--loginutils/deluser.c110
1 files changed, 48 insertions, 62 deletions
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index 795dae49f..e33710175 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -12,85 +12,71 @@
12 12
13#include "busybox.h" 13#include "busybox.h"
14 14
15/* where to start and stop deletion */
16typedef struct {
17 size_t start;
18 size_t stop;
19} Bounds;
20
21/* An interesting side-effect of boundary()'s
22 * implementation is that the first user (typically root)
23 * cannot be removed. Let's call it a feature. */
24static inline Bounds boundary(const char *buffer, const char *login)
25{
26 char needle[256];
27 char *start;
28 char *stop;
29 Bounds b;
30
31 snprintf(needle, 256, "\n%s:", login);
32 needle[255] = 0;
33 start = strstr(buffer, needle);
34 if (!start) {
35 b.start = 0;
36 b.stop = 0;
37 return b;
38 }
39 start++;
40
41 stop = strchr(start, '\n');
42 b.start = start - buffer;
43 b.stop = stop - buffer;
44 return b;
45}
46
47/* grep -v ^login (except it only deletes the first match) */
48/* ...in fact, I think I'm going to simplify this later */
49static void del_line_matching(const char *login, const char *filename) 15static void del_line_matching(const char *login, const char *filename)
50{ 16{
51 char *buffer; 17 char *line;
52 FILE *passwd; 18 FILE *passwd;
53 Bounds b; 19 int len = strlen(login);
54 struct stat statbuf; 20 int found = 0;
21 llist_t *plist = NULL;
22
23 passwd = fopen_or_warn(filename, "r");
24 if (!passwd) return;
25
26 while ((line = xmalloc_fgets(passwd))) {
27 if (!strncmp(line, login, len)
28 && line[len] == ':'
29 ) {
30 found++;
31 free(line);
32 } else {
33 llist_add_to_end(&plist, line);
34 }
35 }
55 36
37 if (!found) {
38 bb_error_msg("can't find '%s' in '%s'", login, filename);
39 if (!ENABLE_FEATURE_CLEAN_UP) return;
40 goto clean_up;
41 }
56 42
57 if ((passwd = fopen_or_warn(filename, "r"))) { 43 if (ENABLE_FEATURE_CLEAN_UP)
58 // Remove pointless const.
59 xstat((char *)filename, &statbuf);
60 buffer = (char *) xmalloc(statbuf.st_size * sizeof(char));
61 fread(buffer, statbuf.st_size, sizeof(char), passwd);
62 fclose(passwd); 44 fclose(passwd);
63 /* find the user to remove */ 45
64 b = boundary(buffer, login); 46 passwd = fopen_or_warn(filename, "w");
65 if (b.stop != 0) { 47 if (passwd) {
66 /* write the file w/o the user */ 48 if (ENABLE_FEATURE_CLEAN_UP) {
67 if ((passwd = fopen_or_warn(filename, "w"))) { 49 clean_up:
68 fwrite(buffer, (b.start - 1), sizeof(char), passwd); 50 while ((line = llist_pop(&plist))) {
69 fwrite(&buffer[b.stop], (statbuf.st_size - b.stop), sizeof(char), passwd); 51 if (found) fputs(line, passwd);
70 fclose(passwd); 52 free(line);
71 } 53 }
54 fclose(passwd);
72 } else { 55 } else {
73 bb_error_msg("can't find '%s' in '%s'", login, filename); 56 /* found != 0 here, no need to check */
57 while ((line = llist_pop(&plist)))
58 fputs(line, passwd);
74 } 59 }
75 free(buffer);
76 } 60 }
77} 61}
78 62
79int deluser_main(int argc, char **argv) 63int deluser_main(int argc, char **argv)
80{ 64{
81 if (argc != 2) { 65 if (argc != 2)
82 bb_show_usage(); 66 bb_show_usage();
83 } else { 67
84 if (ENABLE_DELUSER && applet_name[3] == 'u') { 68 if (ENABLE_DELUSER
85 del_line_matching(argv[1], bb_path_passwd_file); 69 && (!ENABLE_DELGROUP || applet_name[3] == 'u')
86 if (ENABLE_FEATURE_SHADOWPASSWDS) 70 ) {
87 del_line_matching(argv[1], bb_path_shadow_file); 71 del_line_matching(argv[1], bb_path_passwd_file);
88 }
89 del_line_matching(argv[1], bb_path_group_file);
90 if (ENABLE_FEATURE_SHADOWPASSWDS) 72 if (ENABLE_FEATURE_SHADOWPASSWDS)
91 del_line_matching(argv[1], bb_path_gshadow_file); 73 del_line_matching(argv[1], bb_path_shadow_file);
92 } 74 }
93 return (EXIT_SUCCESS); 75 del_line_matching(argv[1], bb_path_group_file);
76 if (ENABLE_FEATURE_SHADOWPASSWDS)
77 del_line_matching(argv[1], bb_path_gshadow_file);
78
79 return EXIT_SUCCESS;
94} 80}
95 81
96/* $Id: deluser.c,v 1.4 2003/07/14 20:20:45 andersen Exp $ */ 82/* $Id: deluser.c,v 1.4 2003/07/14 20:20:45 andersen Exp $ */