|  | // 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; | 
|  | } |