Mercurial > hg > toybox
annotate lib/password.c @ 643:7bdebd2af1d6
Add signal handler to clean up tempfile.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 30 Jul 2012 01:01:33 -0500 |
parents | 9aeea680acc7 |
children | 786841fdb1e0 |
rev | line source |
---|---|
626 | 1 /* vi: set sw=4 ts=4 : |
2 * pwdutils.c - password read/update helper functions. | |
3 * | |
4 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com> | |
5 */ | |
6 | |
7 #include "toys.h" | |
8 #include <time.h> | |
9 | |
10 | |
637
9aeea680acc7
Use "_password" instead of "_passwd" for names in lib/password.c.
Rob Landley <rob@landley.net>
parents:
626
diff
changeset
|
11 int read_password(char * buff, int buflen, char* mesg) |
626 | 12 { |
13 int i = 0; | |
14 struct termios termio, oldtermio; | |
15 tcgetattr(0, &oldtermio); | |
16 tcflush(0, TCIFLUSH); | |
17 termio = oldtermio; | |
18 | |
19 termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); | |
20 termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); | |
21 tcsetattr(0, TCSANOW, &termio); | |
22 | |
23 fputs(mesg, stdout); | |
24 fflush(stdout); | |
25 | |
26 while (1) { | |
27 int ret = read(0, &buff[i], 1); | |
28 if ( ret < 0 ) { | |
29 buff[0] = 0; | |
30 tcsetattr(0, TCSANOW, &oldtermio); | |
31 return 1; | |
32 } | |
33 else if ( ret == 0 || buff[i] == '\n' || | |
34 buff[i] == '\r' || buflen == i+1) { | |
35 buff[i] = '\0'; | |
36 break; | |
37 } | |
38 i++; | |
39 } | |
40 | |
41 tcsetattr(0, TCSANOW, &oldtermio); | |
42 puts(""); | |
43 fflush(stdout); | |
44 return 0; | |
45 } | |
46 | |
47 static char *get_nextcolon(const char *line, char delim) | |
48 { | |
49 char *current_ptr = NULL; | |
50 if((current_ptr = strchr(line, ':')) == NULL) | |
51 error_exit("Invalid Entry\n"); | |
52 return current_ptr; | |
53 } | |
54 | |
637
9aeea680acc7
Use "_password" instead of "_passwd" for names in lib/password.c.
Rob Landley <rob@landley.net>
parents:
626
diff
changeset
|
55 int update_password(char *filename, char* username, char* encrypted) |
626 | 56 { |
57 char *filenamesfx = NULL, *namesfx = NULL; | |
58 char *shadow = NULL, *sfx = NULL; | |
59 FILE *exfp, *newfp; | |
60 int ret = -1; //fail | |
61 struct flock lock; | |
62 char *line = NULL; | |
63 | |
64 shadow = strstr(filename, "shadow"); | |
65 filenamesfx = xmsprintf("%s+", filename); | |
66 sfx = strchr(filenamesfx, '+'); | |
67 | |
68 exfp = fopen(filename, "r+"); | |
69 if(!exfp) { | |
70 perror_msg("Couldn't open file %s",filename); | |
71 goto free_storage; | |
72 } | |
73 | |
74 *sfx = '-'; | |
75 ret = unlink(filenamesfx); | |
76 ret = link(filename, filenamesfx); | |
77 if(ret < 0) error_msg("can't create backup file"); | |
78 | |
79 *sfx = '+'; | |
80 lock.l_type = F_WRLCK; | |
81 lock.l_whence = SEEK_SET; | |
82 lock.l_start = 0; | |
83 lock.l_len = 0; | |
84 | |
85 ret = fcntl(fileno(exfp), F_SETLK, &lock); | |
86 if(ret < 0) perror_msg("Couldn't lock file %s",filename); | |
87 | |
88 lock.l_type = F_UNLCK; //unlocking at a later stage | |
89 | |
90 newfp = fopen(filenamesfx, "w+"); | |
91 if(!newfp) { | |
92 error_msg("couldn't open file for writing"); | |
93 ret = -1; | |
94 fclose(exfp); | |
95 goto free_storage; | |
96 } | |
97 | |
98 ret = 0; | |
99 namesfx = xmsprintf("%s:",username); | |
100 while((line = get_line(fileno(exfp))) != NULL) | |
101 { | |
102 if(strncmp(line, namesfx, strlen(namesfx)) != 0) | |
103 fprintf(newfp, "%s\n", line); | |
104 else { | |
105 char *current_ptr = NULL; | |
106 fprintf(newfp, "%s%s:",namesfx,encrypted); | |
107 current_ptr = get_nextcolon(line, ':'); //past username | |
108 current_ptr++; //past colon ':' after username | |
109 current_ptr = get_nextcolon(current_ptr, ':'); //past passwd | |
110 current_ptr++; //past colon ':' after passwd | |
111 if(shadow) { | |
112 fprintf(newfp, "%u:",(unsigned)(time(NULL))/(24*60*60)); | |
113 current_ptr = get_nextcolon(current_ptr, ':'); | |
114 current_ptr++; //past time stamp colon. | |
115 fprintf(newfp, "%s\n",current_ptr); | |
116 } | |
117 else { | |
118 fprintf(newfp, "%s\n",current_ptr); | |
119 } | |
120 } | |
121 | |
122 free(line); | |
123 } | |
124 free(namesfx); | |
125 fcntl(fileno(exfp), F_SETLK, &lock); | |
126 fclose(exfp); | |
127 | |
128 errno = 0; | |
129 fflush(newfp); | |
130 fsync(fileno(newfp)); | |
131 fclose(newfp); | |
132 rename(filenamesfx, filename); | |
133 if(errno) { | |
134 perror_msg("File Writing/Saving failed: "); | |
135 unlink(filenamesfx); | |
136 ret = -1; | |
137 } | |
138 | |
139 free_storage: | |
140 free(filenamesfx); | |
141 return ret; | |
142 } |