Fix 'smatch' warnings.
[userinfo.git] / contrib / fexists.c
blob9554fb02668a2facec3ec779b2b8883037a8e19a
1 /*
2 Copyright (C) 2001-2011 Ben Kibbey <bjk@luxsci.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA
19 * Userinfo module to check file existance in a users home directory. The only
20 * required flag is -f to specify the filename which only checks for the file
21 * existance and not mode or type. This module is not chainable. It gets the
22 * users home directory from the password structure passed from the main
23 * program.
25 * Compile with: cc -O2 -fPIC -shared -o fexists.so fexists.c
26 * Run with: ui -O ./fexists.so -f filename --
28 * Ben Kibbey <bjk@luxsci.net>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <err.h>
35 #include <pwd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <errno.h>
40 #define F_READ 0x0001
41 #define F_WRITE 0x0002
42 #define F_WRITE_W 0x0004
43 #define F_DIR 0x0008
45 static struct file_s {
46 char *name;
47 unsigned flags;
48 } *files;
50 static int idx;
51 extern void add_string(char ***, const char *);
53 void ui_module_init(int *chainable)
55 *chainable = 0;
58 void ui_module_exit()
60 int i;
62 for (i = 0; i < idx; i++)
63 free(files[i].name);
65 free(files);
66 files = NULL;
67 idx = 0;
70 void ui_module_help()
72 printf(" Check for file existance in a users home directory ([-rwWd] -f <file>).\n");
73 printf("\t-r filename is readable by you\n");
74 printf("\t-w filename is writeable\n");
75 printf("\t-W filename is writeable by you\n");
76 printf("\t-d filename is a directory\n\n");
79 char *ui_module_options_init(char **defaults)
81 *defaults = NULL;
82 return "rwWdf:";
85 int ui_module_options(int argc, char **argv)
87 int opt;
88 unsigned flags = 0;
90 while ((opt = getopt(argc, argv, "f:rwWd")) != -1) {
91 switch (opt) {
92 case 'r':
93 flags |= F_READ;
94 break;
95 case 'w':
96 flags |= F_WRITE;
97 break;
98 case 'W':
99 flags |= F_WRITE_W;
100 break;
101 case 'd':
102 flags |= F_DIR;
103 break;
104 case 'f':
105 if (!flags)
106 return 1;
108 if ((files = realloc(files, (idx + 1) * sizeof(struct file_s))) == NULL) {
109 warn("realloc()");
110 return 1;
113 files[idx].name = strdup(optarg);
114 files[idx++].flags = flags;
115 flags = 0;
116 break;
117 default:
118 return 1;
122 return !files ? 1 : 0;
125 int ui_module_exec(char ***results, const struct passwd *pw, const int msep, const int verbose,
126 const char *tf)
128 char **strings = *results;
129 char buf[FILENAME_MAX];
130 struct stat st;
131 int ret = 0;
132 int i;
134 for (i = 0; i < idx; i++) {
135 ret = 0;
136 snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, files[i].name);
138 if (stat(buf, &st) != -1) {
139 ret = 1;
141 if (files[i].flags & F_READ) {
142 if (access(buf, R_OK) == -1) {
143 ret = 0;
144 goto done;
147 ret = 1;
150 if (files[i].flags & F_WRITE) {
151 if (access(buf, W_OK) == -1) {
152 ret = 0;
153 goto done;
156 ret = 1;
159 if (files[i].flags & F_WRITE) {
160 if (st.st_mode & S_IWOTH)
161 ret = 1;
162 else {
163 ret = 0;
164 goto done;
168 if (files[i].flags & F_DIR) {
169 if (S_ISDIR(st.st_mode))
170 ret = 1;
171 else {
172 ret = 0;
173 goto done;
177 else {
178 if (errno == EACCES)
179 ret = -1;
182 done:
183 if (ret == -1)
184 add_string(&strings, "!");
185 else
186 add_string(&strings, (ret) ? "1" : "0");
189 *results = strings;
190 return 0;