common.c (2743B)
1 /* 2 * Copyright (c) 2014 Mohamed Aslan <maslan@sce.carleton.ca> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 20 #include <string.h> 21 #include <limits.h> 22 #include <unistd.h> 23 24 #include <sys/stat.h> 25 26 #include "defaults.h" 27 #include "common.h" 28 29 30 /* cache the repository root dir for future calls of baseline_repo_get_rootdir() */ 31 static char *repo_rootdir = NULL; 32 static char *repo_baselinedir = NULL; /* repo_rootdir/BASELINE_DIR */ 33 34 int 35 exists(const char *f) 36 { 37 struct stat s; 38 39 if(stat(f, &s) == -1) 40 return 0; 41 return 1; 42 } 43 44 int 45 dir_exists(const char *dir) 46 { 47 struct stat s; 48 49 if (stat(dir, &s) == -1) 50 return 0; 51 if (!S_ISDIR(s.st_mode)) 52 return 0; 53 return 1; 54 } 55 56 static int 57 baseline_validate_repo(const char *path) 58 { 59 char *ptr = NULL; 60 int valid; 61 62 asprintf(&ptr, "%s/%s", path, BASELINE_DIR); 63 if (ptr == NULL) 64 return 0; 65 valid = dir_exists(ptr); 66 /* TODO: use access & check for modes as well */ 67 /* TODO: ask objdb, and may be dircache too */ 68 free(ptr); 69 return valid; 70 } 71 72 /* 73 * may not be so safe 74 * do not free the returned pointer, it will be cached for later calls 75 * try not to use chdir() as possible 76 */ 77 const char * 78 baseline_repo_get_rootdir() 79 { 80 char cwd[PATH_MAX+1]; 81 int i; 82 size_t len; 83 84 /* check if the repository root dir already cached */ 85 if (repo_rootdir != NULL) 86 return repo_rootdir; 87 if (getcwd(cwd, sizeof(cwd)) == NULL) 88 return NULL; 89 len = strlen(cwd); 90 for (i=len-1 ; i>=0 ; i--) { 91 if (cwd[i] == '/') { 92 if (baseline_validate_repo(cwd)) 93 break; 94 cwd[i] = '\0'; 95 } 96 } 97 if (i == -1) { 98 if (baseline_validate_repo(cwd)) 99 repo_rootdir = strdup("/"); 100 else 101 return NULL; 102 } 103 else { 104 repo_rootdir = strdup(cwd); 105 } 106 #ifdef DEBUG 107 printf("repository root dir: %s\n", repo_rootdir); 108 #endif 109 return repo_rootdir; 110 } 111 112 const char* 113 baseline_repo_get_baselinedir() 114 { 115 const char *root_dir; 116 if (repo_baselinedir != NULL) 117 return repo_baselinedir; 118 root_dir = baseline_repo_get_rootdir(); 119 asprintf(&repo_baselinedir, "%s/%s", root_dir, BASELINE_DIR); 120 return repo_baselinedir; 121 } 122