| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * Copyright (c) 2005 Silicon Graphics, Inc. | |
| * All Rights Reserved. | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include "projects.h" | |
| #define PROJID "/etc/projid" | |
| #define PROJECT_PATHS "/etc/projects" | |
| char *projid_file; | |
| char *projects_file; | |
| static FILE *projects; | |
| static FILE *project_paths; | |
| 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) | |
| { | |
| static fs_project_t p; | |
| static char projects_buffer[512]; | |
| 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) | |
| { | |
| static fs_project_path_t pp; | |
| static char project_paths_buffer[1024]; | |
| 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; | |
| } |