diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-21 13:25:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-21 13:25:28 +0000 |
commit | 557fb713e0f943ac9b87c9f3804ba24e73d55bb0 (patch) | |
tree | eda14f3179f0bddf125c2b8e8549cd6e35fa7242 /libbb | |
parent | 1ec5eaecba0a0323f214825b83fabcc18a41884d (diff) | |
download | busybox-w32-557fb713e0f943ac9b87c9f3804ba24e73d55bb0.tar.gz busybox-w32-557fb713e0f943ac9b87c9f3804ba24e73d55bb0.tar.bz2 busybox-w32-557fb713e0f943ac9b87c9f3804ba24e73d55bb0.zip |
chpasswd: fixes and code shrink
update_passwd 732 734 +2
chpasswd_main 318 292 -26
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 2/-26) Total: -24 bytes
text data bss dec hex filename
781564 1168 11900 794632 c2008 busybox_old
781548 1168 11900 794616 c1ff8 busybox_unstripped
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/update_passwd.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c index 5572db547..8914b8b45 100644 --- a/libbb/update_passwd.c +++ b/libbb/update_passwd.c | |||
@@ -18,18 +18,18 @@ int update_passwd(const char *filename, const char *username, | |||
18 | struct flock lock; | 18 | struct flock lock; |
19 | FILE *old_fp; | 19 | FILE *old_fp; |
20 | FILE *new_fp; | 20 | FILE *new_fp; |
21 | char *new_name; | 21 | char *fnamesfx; |
22 | char *last_char; | 22 | char *sfx_char; |
23 | unsigned user_len; | 23 | unsigned user_len; |
24 | int old_fd; | 24 | int old_fd; |
25 | int new_fd; | 25 | int new_fd; |
26 | int i; | 26 | int i; |
27 | int cnt = 0; | 27 | int cnt = 0; |
28 | int ret = 1; /* failure */ | 28 | int ret = -1; /* failure */ |
29 | 29 | ||
30 | /* New passwd file, "/etc/passwd+" for now */ | 30 | /* New passwd file, "/etc/passwd+" for now */ |
31 | new_name = xasprintf("%s+", filename); | 31 | fnamesfx = xasprintf("%s+", filename); |
32 | last_char = &new_name[strlen(new_name)-1]; | 32 | sfx_char = &fnamesfx[strlen(fnamesfx)-1]; |
33 | username = xasprintf("%s:", username); | 33 | username = xasprintf("%s:", username); |
34 | user_len = strlen(username); | 34 | user_len = strlen(username); |
35 | 35 | ||
@@ -42,12 +42,12 @@ int update_passwd(const char *filename, const char *username, | |||
42 | i = 30; | 42 | i = 30; |
43 | do { | 43 | do { |
44 | // FIXME: on last iteration try w/o O_EXCL but with O_TRUNC? | 44 | // FIXME: on last iteration try w/o O_EXCL but with O_TRUNC? |
45 | new_fd = open(new_name, O_WRONLY|O_CREAT|O_EXCL,0600); | 45 | new_fd = open(fnamesfx, O_WRONLY|O_CREAT|O_EXCL, 0600); |
46 | if (new_fd >= 0) goto created; | 46 | if (new_fd >= 0) goto created; |
47 | if (errno != EEXIST) break; | 47 | if (errno != EEXIST) break; |
48 | usleep(100000); /* 0.1 sec */ | 48 | usleep(100000); /* 0.1 sec */ |
49 | } while (--i); | 49 | } while (--i); |
50 | bb_perror_msg("cannot create '%s'", new_name); | 50 | bb_perror_msg("cannot create '%s'", fnamesfx); |
51 | goto close_old_fp; | 51 | goto close_old_fp; |
52 | 52 | ||
53 | created: | 53 | created: |
@@ -62,12 +62,13 @@ int update_passwd(const char *filename, const char *username, | |||
62 | } | 62 | } |
63 | 63 | ||
64 | /* Backup file is "/etc/passwd-" */ | 64 | /* Backup file is "/etc/passwd-" */ |
65 | last_char[0] = '-'; | 65 | *sfx_char = '-'; |
66 | /* Delete old one, create new as a hardlink to current */ | 66 | /* Delete old backup */ |
67 | i = (unlink(new_name) && errno != ENOENT); | 67 | i = (unlink(fnamesfx) && errno != ENOENT); |
68 | if (i || link(filename, new_name)) | 68 | /* Create backup as a hardlink to current */ |
69 | bb_perror_msg("warning: cannot create backup copy '%s'", new_name); | 69 | if (i || link(filename, fnamesfx)) |
70 | last_char[0] = '+'; | 70 | bb_perror_msg("warning: cannot create backup copy '%s'", fnamesfx); |
71 | *sfx_char = '+'; | ||
71 | 72 | ||
72 | /* Lock the password file before updating */ | 73 | /* Lock the password file before updating */ |
73 | lock.l_type = F_WRLCK; | 74 | lock.l_type = F_WRLCK; |
@@ -78,7 +79,7 @@ int update_passwd(const char *filename, const char *username, | |||
78 | bb_perror_msg("warning: cannot lock '%s'", filename); | 79 | bb_perror_msg("warning: cannot lock '%s'", filename); |
79 | lock.l_type = F_UNLCK; | 80 | lock.l_type = F_UNLCK; |
80 | 81 | ||
81 | /* Read current password file, write updated one */ | 82 | /* Read current password file, write updated /etc/passwd+ */ |
82 | while (1) { | 83 | while (1) { |
83 | char *line = xmalloc_fgets(old_fp); | 84 | char *line = xmalloc_fgets(old_fp); |
84 | if (!line) break; /* EOF/error */ | 85 | if (!line) break; /* EOF/error */ |
@@ -86,8 +87,7 @@ int update_passwd(const char *filename, const char *username, | |||
86 | /* we have a match with "username:"... */ | 87 | /* we have a match with "username:"... */ |
87 | const char *cp = line + user_len; | 88 | const char *cp = line + user_len; |
88 | /* now cp -> old passwd, skip it: */ | 89 | /* now cp -> old passwd, skip it: */ |
89 | cp = strchr(cp, ':'); | 90 | cp = strchrnul(cp, ':'); |
90 | if (!cp) cp = ""; | ||
91 | /* now cp -> ':' after old passwd or -> "" */ | 91 | /* now cp -> ':' after old passwd or -> "" */ |
92 | fprintf(new_fp, "%s%s%s", username, new_pw, cp); | 92 | fprintf(new_fp, "%s%s%s", username, new_pw, cp); |
93 | cnt++; | 93 | cnt++; |
@@ -99,7 +99,7 @@ int update_passwd(const char *filename, const char *username, | |||
99 | 99 | ||
100 | /* We do want all of them to execute, thus | instead of || */ | 100 | /* We do want all of them to execute, thus | instead of || */ |
101 | if ((ferror(old_fp) | fflush(new_fp) | fsync(new_fd) | fclose(new_fp)) | 101 | if ((ferror(old_fp) | fflush(new_fp) | fsync(new_fd) | fclose(new_fp)) |
102 | || rename(new_name, filename) | 102 | || rename(fnamesfx, filename) |
103 | ) { | 103 | ) { |
104 | /* At least one of those failed */ | 104 | /* At least one of those failed */ |
105 | goto unlink_new; | 105 | goto unlink_new; |
@@ -107,13 +107,13 @@ int update_passwd(const char *filename, const char *username, | |||
107 | ret = cnt; /* whee, success! */ | 107 | ret = cnt; /* whee, success! */ |
108 | 108 | ||
109 | unlink_new: | 109 | unlink_new: |
110 | if (ret) unlink(new_name); | 110 | if (ret < 0) unlink(fnamesfx); |
111 | 111 | ||
112 | close_old_fp: | 112 | close_old_fp: |
113 | fclose(old_fp); | 113 | fclose(old_fp); |
114 | 114 | ||
115 | free_mem: | 115 | free_mem: |
116 | if (ENABLE_FEATURE_CLEAN_UP) free(new_name); | 116 | free(fnamesfx); |
117 | if (ENABLE_FEATURE_CLEAN_UP) free((char*)username); | 117 | free((char*)username); |
118 | return ret; | 118 | return ret; |
119 | } | 119 | } |