OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / tinylogin / deluser.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * deluser (remove lusers from the system ;) for TinyLogin
4  *
5  *
6  * Copyright (C) 1999 by Lineo, inc.
7  * Written by John Beppu <beppu@lineo.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  */
24
25 #include "tinylogin.h"
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32
33 /* where to start and stop deletion */
34 typedef struct {
35         size_t start;
36         size_t stop;
37 } Bounds;
38
39 /* An interesting side-effect of boundary()'s
40  * implementation is that the first user (typically root)
41  * cannot be removed.  Let's call it a feature. */
42 static Bounds boundary(const char *buffer, const char *login)
43 {
44         char needle[256];
45         char *start;
46         char *stop;
47         Bounds b;
48
49         snprintf(needle, 256, "\n%s", login);
50         needle[255] = 0;
51         start = strstr(buffer, needle);
52         if (!start) {
53                 b.start = 0;
54                 b.stop = 0;
55                 return b;
56         }
57         start++;
58
59         stop = index(start, '\n');      /* index is a BSD-ism */
60         b.start = start - buffer;
61         b.stop = stop - buffer;
62         return b;
63 }
64
65 /* grep -v ^login (except it only deletes the first match) */
66 /* ...in fact, I think I'm going to simplify this later */
67 static int del_line_matching(char *login, char *filename)
68 {
69         char *buffer;
70         FILE *passwd;
71         size_t len;
72         Bounds b;
73         struct stat statbuf;
74
75         /* load into buffer */
76         passwd = fopen(filename, "r");
77         if (!passwd) {
78                 return 1;
79         }
80         stat(filename, &statbuf);
81         len = statbuf.st_size;
82         buffer = (char *) malloc(len * sizeof(char));
83
84         if (!buffer) {
85                 fclose(passwd);
86                 return 1;
87         }
88         fread(buffer, len, sizeof(char), passwd);
89
90         fclose(passwd);
91
92         /* find the user to remove */
93         b = boundary(buffer, login);
94         if (b.stop == 0) {
95                 free(buffer);
96                 return 1;
97         }
98
99         /* write the file w/o the user */
100         passwd = fopen(filename, "w");
101         if (!passwd) {
102                 return 1;
103         }
104         fwrite(buffer, (b.start - 1), sizeof(char), passwd);
105         fwrite(&buffer[b.stop], (len - b.stop), sizeof(char), passwd);
106
107         fclose(passwd);
108
109         return 0;
110 }
111
112 /* ________________________________________________________________________ */
113 int delgroup_main(int argc, char **argv)
114 {
115         /* int successful; */
116         int failure;
117
118         if (argc != 2) {
119                 usage(delgroup_usage);
120         } else {
121
122                 failure = del_line_matching(argv[1], GROUP_FILE);
123 #ifdef TLG_FEATURE_SHADOWPASSWDS
124                 if (access(GSHADOW_FILE, W_OK) == 0) {
125                         /* EDR the |= works if the error is not 0, so he had it wrong */
126                         failure |= del_line_matching(argv[1], GSHADOW_FILE);
127                 }
128 #endif                                                  /* TLG_FEATURE_SHADOWPASSWDS */
129                 /* if (!successful) { */
130                 if (failure) {
131                         error_msg_and_die("%s: Group could not be removed\n", argv[1]);
132                 }
133
134         }
135         return (EXIT_SUCCESS);
136 }
137
138 /* ________________________________________________________________________ */
139 int deluser_main(int argc, char **argv)
140 {
141         /* int successful; */
142         int failure;
143
144         if (argc != 2) {
145                 usage(deluser_usage);
146         } else {
147
148                 failure = del_line_matching(argv[1], PASSWD_FILE);
149                 /* if (!successful) { */
150                 if (failure) {
151                         error_msg_and_die("%s: User could not be removed from %s\n",
152                                                           argv[1], PASSWD_FILE);
153                 }
154 #ifdef TLG_FEATURE_SHADOWPASSWDS
155                 failure = del_line_matching(argv[1], SHADOW_FILE);
156                 /* if (!successful) { */
157                 if (failure) {
158                         error_msg_and_die("%s: User could not be removed from %s\n",
159                                                           argv[1], SHADOW_FILE);
160                 }
161 #endif                                                  /* TLG_FEATURE_SHADOWPASSWDS */
162                 failure = del_line_matching(argv[1], GROUP_FILE);
163                 /* if (!successful) { */
164                 if (failure) {
165                         error_msg_and_die("%s: User could not be removed from %s\n",
166                                                           argv[1], GROUP_FILE);
167                 }
168
169         }
170         return (EXIT_SUCCESS);
171 }
172
173 /* $Id: deluser.c,v 1.3 2001-08-20 07:47:31 philipc Exp $ */