| /* |
| * Copyright (c) 2005 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it would be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "project.h" |
| |
| #define PROJID "/etc/projid" |
| #define PROJECT_PATHS "/etc/projects" |
| char *projid_file; |
| char *projects_file; |
| |
| static FILE *projects; |
| static fs_project_t p; |
| static char projects_buffer[512]; |
| |
| static FILE *project_paths; |
| static fs_project_path_t pp; |
| static char project_paths_buffer[1024]; |
| |
| void |
| setprfiles(void) |
| { |
| if (!projid_file) |
| projid_file = PROJID; |
| if (!projects_file) |
| projects_file = PROJECT_PATHS; |
| } |
| |
| void |
| setprent(void) |
| { |
| setprfiles(); |
| projects = fopen(projid_file, "r"); |
| } |
| |
| void |
| setprpathent(void) |
| { |
| setprfiles(); |
| project_paths = fopen(projects_file, "r"); |
| } |
| |
| void |
| endprent(void) |
| { |
| if (projects) |
| fclose(projects); |
| projects = NULL; |
| } |
| |
| void |
| endprpathent(void) |
| { |
| if (project_paths) |
| fclose(project_paths); |
| project_paths = NULL; |
| } |
| |
| fs_project_t * |
| getprent(void) |
| { |
| char *idstart, *idend; |
| size_t size = sizeof(projects_buffer) - 1; |
| |
| if (!projects) |
| return NULL; |
| for (;;) { |
| if (!fgets(projects_buffer, size, projects)) |
| break; |
| /* |
| * /etc/projid file format -- "name:id\n", ignore "^#..." |
| */ |
| if (projects_buffer[0] == '#') |
| continue; |
| idstart = strchr(projects_buffer, ':'); |
| if (!idstart) |
| continue; |
| if ((idstart + 1) - projects_buffer >= size) |
| continue; |
| idend = strchr(idstart+1, ':'); |
| if (idend) |
| *idend = '\0'; |
| *idstart = '\0'; |
| p.pr_prid = atoi(idstart+1); |
| p.pr_name = &projects_buffer[0]; |
| return &p; |
| } |
| |
| return NULL; |
| } |
| |
| fs_project_t * |
| getprnam( |
| char *name) |
| { |
| fs_project_t *p = NULL; |
| |
| setprent(); |
| while ((p = getprent()) != NULL) |
| if (strcmp(p->pr_name, name) == 0) |
| break; |
| endprent(); |
| return p; |
| } |
| |
| fs_project_t * |
| getprprid( |
| prid_t prid) |
| { |
| fs_project_t *p = NULL; |
| |
| setprent(); |
| while ((p = getprent()) != NULL) |
| if (p->pr_prid == prid) |
| break; |
| endprent(); |
| return p; |
| } |
| |
| fs_project_path_t * |
| getprpathent(void) |
| { |
| char *nmstart, *nmend; |
| size_t size = sizeof(project_paths_buffer) - 1; |
| |
| if (!project_paths) |
| return NULL; |
| for (;;) { |
| if (!fgets(project_paths_buffer, size, project_paths)) |
| break; |
| /* |
| * /etc/projects format -- "id:pathname\n", ignore "^#..." |
| */ |
| if (project_paths_buffer[0] == '#') |
| continue; |
| nmstart = strchr(project_paths_buffer, ':'); |
| if (!nmstart) |
| continue; |
| if ((nmstart + 1) - project_paths_buffer >= size) |
| continue; |
| nmend = strchr(nmstart + 1, '\n'); |
| if (nmend) |
| *nmend = '\0'; |
| *nmstart = '\0'; |
| pp.pp_pathname = nmstart + 1; |
| pp.pp_prid = atoi(&project_paths_buffer[0]); |
| return &pp; |
| } |
| |
| return NULL; |
| } |
| |
| |
| int |
| getprojid( |
| const char *name, |
| int fd, |
| prid_t *projid) |
| { |
| struct fsxattr fsx; |
| |
| if (xfsctl(name, fd, FS_IOC_FSGETXATTR, &fsx)) { |
| perror("FS_IOC_FSGETXATTR"); |
| return -1; |
| } |
| *projid = fsx.fsx_projid; |
| return 0; |
| } |
| |
| int |
| setprojid( |
| const char *name, |
| int fd, |
| prid_t projid) |
| { |
| struct fsxattr fsx; |
| int error; |
| |
| if ((error = xfsctl(name, fd, FS_IOC_FSGETXATTR, &fsx)) == 0) { |
| fsx.fsx_projid = projid; |
| error = xfsctl(name, fd, FS_IOC_FSSETXATTR, &fsx); |
| } |
| return error; |
| } |