nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 #ifdef HAVE_CONFIG_H 00005 #include "config.h" 00006 #endif 00007 00008 #include "fsal.h" 00009 #include "fsal_internal.h" 00010 #include "abstract_mem.h" 00011 #include <string.h> 00012 #include <unistd.h> 00013 #include <libgen.h> /* basename */ 00014 #include <sys/types.h> 00015 #include <sys/stat.h> 00016 00017 #define OP_TESTCONN 1 00018 #define OP_EMPTYDB 2 00019 #define OP_FIND 3 00020 #define OP_POPULATE 4 00021 00022 /* functions related to OP_FIND */ 00023 void find(fsal_posixdb_conn * p_conn); 00024 void display_directory(fsal_posixdb_conn * p_conn, posixfsal_handle_t * p_handle_parent, 00025 char *basedir); 00026 00027 /* functions related to OP_EMPTYDB */ 00028 void emptydb(fsal_posixdb_conn * p_conn); 00029 00030 /* functions related to OP_POPULATE */ 00031 void populatedb(fsal_posixdb_conn * p_conn, char *path); 00032 void add_dir(fsal_posixdb_conn * p_conn, char *path, posixfsal_handle_t * dir_handle); 00033 00034 /* ---------------------------------------------- */ 00035 00036 void populatedb(fsal_posixdb_conn * p_conn, char *path) 00037 { 00038 int rc; 00039 fsal_posixdb_fileinfo_t info; 00040 fsal_name_t fsalname; 00041 posixfsal_handle_t handle, handle_parent; 00042 struct stat buffstat; 00043 char *begin, *end, backup; 00044 00045 if(path[0] != '/') 00046 { 00047 fputs("Error : you should provide a complete path", stderr); 00048 return; 00049 } 00050 00051 if(path[strlen(path) - 1] != '/') 00052 strcat(path, "/"); 00053 00054 /* add the path (given in arguments) to the database */ 00055 rc = lstat("/", &buffstat); 00056 fsal_internal_posix2posixdb_fileinfo(&buffstat, &info); 00057 fsal_internal_posixdb_add_entry(p_conn, NULL, &info, NULL, &handle_parent); 00058 00059 begin = end = path; 00060 while(*end != '\0') 00061 { 00062 while(*begin == '/') 00063 begin++; 00064 if(*begin == '\0') 00065 break; 00066 end = begin + 1; 00067 while(*end != '/' && *end != '\0') 00068 end++; 00069 backup = *end; 00070 *end = '\0'; 00071 00072 rc = lstat(path, &buffstat); 00073 fsal_internal_posix2posixdb_fileinfo(&buffstat, &info); 00074 FSAL_str2name(begin, FSAL_MAX_NAME_LEN, &fsalname); 00075 fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, &handle_parent, &handle); 00076 memcpy(&handle_parent, &handle, sizeof(posixfsal_handle_t)); 00077 00078 *end = backup; 00079 begin = end; 00080 } 00081 00082 /* add files */ 00083 printf("Adding entries in %s... rc=%d ", path, rc); 00084 fflush(stdout); 00085 add_dir(p_conn, path, &handle_parent); 00086 puts("done"); 00087 } 00088 00089 void add_dir(fsal_posixdb_conn * p_conn, char *path, posixfsal_handle_t * p_dir_handle) 00090 { 00091 DIR *dirp; 00092 struct dirent *dp; 00093 struct dirent dpe; 00094 posixfsal_handle_t new_handle; 00095 struct stat buffstat; 00096 char path_temp[FSAL_MAX_PATH_LEN]; 00097 fsal_status_t st; 00098 fsal_posixdb_fileinfo_t info; 00099 fsal_name_t fsalname; 00100 00101 if((dirp = opendir(path))) 00102 { 00103 while(!readdir_r(dirp, &dpe, &dp) && dp) 00104 { 00105 if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) 00106 continue; 00107 if(!strcmp(dp->d_name, ".snapshot")) 00108 { 00109 fputs("(ignoring .snapshot)", stderr); 00110 continue; 00111 } 00112 strcpy(path_temp, path); 00113 strcat(path_temp, dp->d_name); 00114 lstat(path_temp, &buffstat); 00115 00116 fsal_internal_posix2posixdb_fileinfo(&buffstat, &info); 00117 FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &fsalname); 00118 st = fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, p_dir_handle, 00119 &new_handle); 00120 if(FSAL_IS_ERROR(st)) 00121 { 00122 fprintf(stderr, "[Error %i/%i]\n", st.major, st.minor); 00123 return; 00124 } 00125 if(S_ISDIR(buffstat.st_mode)) 00126 { 00127 strcat(path_temp, "/"); 00128 add_dir(p_conn, path_temp, &new_handle); 00129 } 00130 }; 00131 closedir(dirp); 00132 } 00133 } 00134 00135 void emptydb(fsal_posixdb_conn * p_conn) 00136 { 00137 fsal_posixdb_status_t st; 00138 00139 st = fsal_posixdb_flush(p_conn); 00140 if(FSAL_POSIXDB_IS_ERROR(st)) 00141 { 00142 fprintf(stderr, "Error (%i/%i) while emptying the database\n", st.major, st.minor); 00143 } 00144 else 00145 { 00146 printf("Database entries have been successfully deleted\n"); 00147 } 00148 00149 return; 00150 } 00151 00152 void find(fsal_posixdb_conn * p_conn) 00153 { 00154 posixfsal_handle_t handle_root; 00155 fsal_posixdb_status_t st; 00156 00157 st = fsal_posixdb_getInfoFromName(p_conn, NULL, /* parent handle */ 00158 NULL, /* filename */ 00159 NULL, /* path */ 00160 &handle_root); 00161 if(FSAL_POSIXDB_IS_NOENT(st)) 00162 { 00163 fputs("Error : Root handle not found. Is the database empty ?", stderr); 00164 return; 00165 } 00166 else if(FSAL_POSIXDB_IS_ERROR(st)) 00167 { 00168 fprintf(stderr, "Error (%i/%i) while getting root handle\n", st.major, st.minor); 00169 return; 00170 } 00171 00172 display_directory(p_conn, &handle_root, ""); 00173 return; 00174 } 00175 00176 void display_directory(fsal_posixdb_conn * p_conn, posixfsal_handle_t * p_handle_parent, 00177 char *basedir) 00178 { 00179 fsal_posixdb_child *p_children; 00180 fsal_posixdb_status_t st; 00181 unsigned int count, i; 00182 00183 st = fsal_posixdb_getChildren(p_conn, p_handle_parent, 0, &p_children, &count); 00184 if(FSAL_POSIXDB_IS_ERROR(st)) 00185 { 00186 fprintf(stderr, "Error (%i/%i) while getting children of %s\n", st.major, st.minor, 00187 basedir); 00188 return; 00189 } 00190 for(i = 0; i < count; i++) 00191 { 00192 printf("%llu %s/%s\n", (unsigned long long int)p_children[i].handle.data.info.inode, 00193 basedir, p_children[i].name.name); 00194 if(p_children[i].handle.data.info.ftype == FSAL_TYPE_DIR) 00195 { 00196 char basedir_new[FSAL_MAX_PATH_LEN]; 00197 00198 memset( basedir_new, 0, FSAL_MAX_PATH_LEN ) ; 00199 strncpy(basedir_new, basedir, FSAL_MAX_PATH_LEN); 00200 strncat(basedir_new, "/", FSAL_MAX_PATH_LEN); 00201 strncat(basedir_new, p_children[i].name.name, FSAL_MAX_PATH_LEN); 00202 display_directory(p_conn, &(p_children[i].handle), basedir_new); 00203 } 00204 } 00205 gsh_free(p_children); 00206 } 00207 00208 int main(int argc, char **argv) 00209 { 00210 fsal_posixdb_conn_params_t dbparams; 00211 char exec_name[MAXPATHLEN]; 00212 char c, op = 0; 00213 fsal_posixdb_conn *p_conn; 00214 fsal_posixdb_status_t statusdb; 00215 char path[MAXPATHLEN]; 00216 int rc; 00217 00218 char options[] = "h@H:P:L:D:K:"; 00219 char usage[] = 00220 "Usage: %s [-h][-H <host>][-P <port>][-L <login>][-D <dbname>][-K <passwd file>] operation operation_parameters\n" 00221 "\t[-h] display this help\n" 00222 "\t[-H <host>] Database host\n" 00223 "\t[-P <port>] Database port\n" 00224 "\t[-L <login>] Database login\n" 00225 "\t[-D <dbname>] Name of the database\n" 00226 "\t[-K <passwd file>] Path of the file where is stored the password\n" 00227 "------------- Default Values -------------\n" 00228 "host : localhost\n" 00229 "port : default DB port\n" 00230 "dbname : posixdb\n" 00231 "login : current unix user\n" 00232 "passwd file : default path ($PGPASSFILE)\n" 00233 "------------- Operations -----------------\n" 00234 "test_connection : try to connect to the database\n" 00235 "empty_database : Delete all entries in the database\n" 00236 "find : Print the entries of the database (as 'find' would do it)\n" 00237 "populate <path> : Add (recursively) the object in <path> into the database\n\n"; 00238 00239 memset(&dbparams, 0, sizeof(fsal_posixdb_conn_params_t)); 00240 strcpy(dbparams.host, "localhost"); 00241 strcpy(dbparams.dbname, "posixdb"); 00242 00243 /* What is the executable file's name */ 00244 if(*exec_name == '\0') 00245 strcpy((char *)exec_name, basename(argv[0])); 00246 00247 /* now parsing options with getopt */ 00248 while((c = getopt(argc, argv, options)) != EOF) 00249 { 00250 switch (c) 00251 { 00252 case '@': 00253 /* A litlle backdoor to keep track of binary versions */ 00254 printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); 00255 exit(0); 00256 break; 00257 case 'H': 00258 strncpy(dbparams.host, optarg, FSAL_MAX_DBHOST_NAME_LEN); 00259 break; 00260 case 'P': 00261 strncpy(dbparams.port, optarg, FSAL_MAX_DBPORT_STR_LEN); 00262 break; 00263 case 'L': 00264 strncpy(dbparams.login, optarg, FSAL_MAX_DB_LOGIN_LEN); 00265 break; 00266 case 'D': 00267 strncpy(dbparams.dbname, optarg, FSAL_MAX_DB_NAME_LEN); 00268 break; 00269 case 'K': 00270 strncpy(dbparams.passwdfile, optarg, PATH_MAX); 00271 break; 00272 default: 00273 /* display the help */ 00274 fprintf(stderr, usage, exec_name); 00275 exit(0); 00276 break; 00277 } 00278 } 00279 00280 if(optind == argc) 00281 { 00282 fprintf(stderr, "No operation specified.\n"); 00283 fprintf(stderr, usage, exec_name); 00284 exit(0); 00285 } 00286 if(optind < argc) 00287 { 00288 if(!strcmp(argv[optind], "test_connection")) 00289 { 00290 op = OP_TESTCONN; 00291 } 00292 else if(!strcmp(argv[optind], "empty_database")) 00293 { 00294 op = OP_EMPTYDB; 00295 } 00296 else if(!strcmp(argv[optind], "find")) 00297 { 00298 op = OP_FIND; 00299 } 00300 else if(!strcmp(argv[optind], "populate")) 00301 { 00302 op = OP_POPULATE; 00303 optind++; 00304 if(optind < argc) 00305 { 00306 strncpy(path, argv[optind], MAXPATHLEN); 00307 } 00308 else 00309 { 00310 fputs("Operation 'populate' need a parameter", stderr); 00311 fprintf(stderr, usage, exec_name); 00312 exit(-1); 00313 } 00314 } 00315 else 00316 { 00317 fprintf(stderr, "Unknown operation : %s\n", argv[optind]); 00318 fprintf(stderr, usage, exec_name); 00319 exit(-1); 00320 } 00321 } 00322 00323 /* Connecting to database */ 00324 if(*(dbparams.passwdfile) != '\0') 00325 { 00326 rc = setenv("PGPASSFILE", dbparams.passwdfile, 1); 00327 if(rc != 0) 00328 fputs("Could not set POSTGRESQL keytab path.", stderr); 00329 } 00330 00331 fprintf(stderr, "Opening database connection to %s...\n", dbparams.host); 00332 statusdb = fsal_posixdb_connect(&dbparams, &p_conn); 00333 if(FSAL_POSIXDB_IS_ERROR(statusdb)) 00334 { 00335 fprintf(stderr, "Error %i. exiting.\n", statusdb.minor); 00336 exit(-1); 00337 } 00338 else 00339 { 00340 fprintf(stderr, "Connected.\n"); 00341 } 00342 00343 /* Execute the operation */ 00344 switch (op) 00345 { 00346 case OP_TESTCONN: 00347 /* nothing to do */ 00348 break; 00349 case OP_EMPTYDB: 00350 emptydb(p_conn); 00351 break; 00352 case OP_FIND: 00353 find(p_conn); 00354 break; 00355 case OP_POPULATE: 00356 populatedb(p_conn, path); 00357 break; 00358 default: 00359 puts("Bad operation !!"); 00360 fprintf(stderr, usage, exec_name); 00361 } 00362 00363 fsal_posixdb_disconnect(p_conn); 00364 00365 exit(0); 00366 }