]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/projects.c
xfsprogs: libxcmd: allow 0 as a wildcard fs_table entry type selector
[thirdparty/xfsprogs-dev.git] / libxcmd / projects.c
1 /*
2 * Copyright (c) 2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would 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.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <xfs/project.h>
23
24 #define PROJID "/etc/projid"
25 #define PROJECT_PATHS "/etc/projects"
26 char *projid_file;
27 char *projects_file;
28
29 static FILE *projects;
30 static fs_project_t p;
31 static char projects_buffer[512];
32
33 static FILE *project_paths;
34 static fs_project_path_t pp;
35 static char project_paths_buffer[1024];
36
37 void
38 setprfiles(void)
39 {
40 if (!projid_file)
41 projid_file = PROJID;
42 if (!projects_file)
43 projects_file = PROJECT_PATHS;
44 }
45
46 void
47 setprent(void)
48 {
49 setprfiles();
50 projects = fopen(projid_file, "r");
51 }
52
53 void
54 setprpathent(void)
55 {
56 setprfiles();
57 project_paths = fopen(projects_file, "r");
58 }
59
60 void
61 endprent(void)
62 {
63 if (projects)
64 fclose(projects);
65 projects = NULL;
66 }
67
68 void
69 endprpathent(void)
70 {
71 if (project_paths)
72 fclose(project_paths);
73 project_paths = NULL;
74 }
75
76 fs_project_t *
77 getprent(void)
78 {
79 char *idstart, *idend;
80 size_t size = sizeof(projects_buffer) - 1;
81
82 if (!projects)
83 return NULL;
84 for (;;) {
85 if (!fgets(projects_buffer, size, projects))
86 break;
87 /*
88 * /etc/projid file format -- "name:id\n", ignore "^#..."
89 */
90 if (projects_buffer[0] == '#')
91 continue;
92 idstart = strchr(projects_buffer, ':');
93 if (!idstart)
94 continue;
95 if ((idstart + 1) - projects_buffer >= size)
96 continue;
97 idend = strchr(idstart+1, ':');
98 if (idend)
99 *idend = '\0';
100 *idstart = '\0';
101 p.pr_prid = atoi(idstart+1);
102 p.pr_name = &projects_buffer[0];
103 return &p;
104 }
105
106 return NULL;
107 }
108
109 fs_project_t *
110 getprnam(
111 char *name)
112 {
113 fs_project_t *p = NULL;
114
115 setprent();
116 while ((p = getprent()) != NULL)
117 if (strcmp(p->pr_name, name) == 0)
118 break;
119 endprent();
120 return p;
121 }
122
123 fs_project_t *
124 getprprid(
125 prid_t prid)
126 {
127 fs_project_t *p = NULL;
128
129 setprent();
130 while ((p = getprent()) != NULL)
131 if (p->pr_prid == prid)
132 break;
133 endprent();
134 return p;
135 }
136
137 fs_project_path_t *
138 getprpathent(void)
139 {
140 char *nmstart, *nmend;
141 size_t size = sizeof(project_paths_buffer) - 1;
142
143 if (!project_paths)
144 return NULL;
145 for (;;) {
146 if (!fgets(project_paths_buffer, size, project_paths))
147 break;
148 /*
149 * /etc/projects format -- "id:pathname\n", ignore "^#..."
150 */
151 if (project_paths_buffer[0] == '#')
152 continue;
153 nmstart = strchr(project_paths_buffer, ':');
154 if (!nmstart)
155 continue;
156 if ((nmstart + 1) - project_paths_buffer >= size)
157 continue;
158 nmend = strchr(nmstart + 1, '\n');
159 if (nmend)
160 *nmend = '\0';
161 *nmstart = '\0';
162 pp.pp_pathname = nmstart + 1;
163 pp.pp_prid = atoi(&project_paths_buffer[0]);
164 return &pp;
165 }
166
167 return NULL;
168 }
169
170
171 int
172 getprojid(
173 const char *name,
174 int fd,
175 prid_t *projid)
176 {
177 struct fsxattr fsx;
178
179 if (xfsctl(name, fd, XFS_IOC_FSGETXATTR, &fsx)) {
180 perror("XFS_IOC_FSGETXATTR");
181 return -1;
182 }
183 *projid = fsx.fsx_projid;
184 return 0;
185 }
186
187 int
188 setprojid(
189 const char *name,
190 int fd,
191 prid_t projid)
192 {
193 struct fsxattr fsx;
194 int error;
195
196 if ((error = xfsctl(name, fd, XFS_IOC_FSGETXATTR, &fsx)) == 0) {
197 fsx.fsx_projid = projid;
198 error = xfsctl(name, fd, XFS_IOC_FSSETXATTR, &fsx);
199 }
200 return error;
201 }