diff options
| author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-11-27 00:54:59 +0000 |
|---|---|---|
| committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-11-27 00:54:59 +0000 |
| commit | e09b10b548e2d5c58680edb4a45cbaf70587fadc (patch) | |
| tree | 82508111fa3dc475a52260b1096353b6bf5782d2 | |
| parent | c13d65bc638ecdd0a9c41294ce08eec1d8dc43d8 (diff) | |
| download | busybox-w32-e09b10b548e2d5c58680edb4a45cbaf70587fadc.tar.gz busybox-w32-e09b10b548e2d5c58680edb4a45cbaf70587fadc.tar.bz2 busybox-w32-e09b10b548e2d5c58680edb4a45cbaf70587fadc.zip | |
deluser: size reduction by 60 bytes.
patch from Tito <farmatito@tiscali.it>
git-svn-id: svn://busybox.net/trunk/busybox@16680 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -rw-r--r-- | loginutils/deluser.c | 110 |
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 */ | ||
| 16 | typedef 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. */ | ||
| 24 | static 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 */ | ||
| 49 | static void del_line_matching(const char *login, const char *filename) | 15 | static 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 | ||
| 79 | int deluser_main(int argc, char **argv) | 63 | int 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 $ */ |
