/**************************************************************************** * OBIDMS column directories functions * ****************************************************************************/ /** * @file obidmscolumndir.c * @author Celine Mercier * @date 18 June 2015 * @brief Functions for OBIDMS column directories. */ #include #include #include #include #include #include #include "obidmscolumndir.h" #include "obidms.h" #include "private_at_functions.h" #include "obierrno.h" /************************************************************************** * * D E C L A R A T I O N O F T H E P R I V A T E F U N C T I O N S * **************************************************************************/ /** * Internal function building the column directory name from an OBIDMS column name. * * The function builds the directory name corresponding to an OBIDMS column directory. * It checks also that the name is not too long. * * @warning The returned pointer has to be freed by the caller. * * @param column_name the name of the OBIDMS column * * @return a pointer to the OBIDMS column directory name * @retvalue if everything is ok * @retvalue NULL if an error occurs * * ###Error values * - OBIDMS_MEMORY_ERROR : something wrong occurred during memory allocation. * - OBIDMS_LONG_NAME_ERROR : the database name exceeds the limit. * * @since June 2015 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ static char* build_column_directory_name(const char* column_name); /************************************************************************ * * D E F I N I T I O N O F T H E P R I V A T E F U N C T I O N S * ************************************************************************/ static char* build_column_directory_name(const char* column_name) { char* column_directory_name; // Build the database directory name if (asprintf(&column_directory_name, "%s.obicol", column_name) < 0) { obi_set_errno(OBICOLDIR_MEMORY_ERROR); return NULL; } // Test if the database name is not too long if (strlen(column_directory_name) >= OBIDMS_COLUMN_DIR_MAX_NAME) { obi_set_errno(OBICOLDIR_LONG_NAME_ERROR); free(column_directory_name); return NULL; } return column_directory_name; } /********************************************************************** * * D E F I N I T I O N O F T H E P U B L I C F U N C T I O N S * **********************************************************************/ int obi_column_directory_exists(OBIDMS_p dms, const char* column_name) { struct stat buffer; char* column_directory_name; char* full_path; int check_dir; int dms_file_descriptor; // Build and check the directory name column_directory_name = build_column_directory_name(column_name); if (column_directory_name == NULL) { obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); return -1; } // Get the file descriptor for the dms dms_file_descriptor = dirfd(dms->directory); if (dms_file_descriptor < 0) { obi_set_errno(OBIDMS_UNKNOWN_ERROR); free(column_directory_name); return -1; } // Get the full path for the column directory full_path = get_full_path(dms_file_descriptor, column_directory_name); if (full_path == NULL) { obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); free(column_directory_name); return -1; } check_dir = stat(full_path, &buffer); free(column_directory_name); free(full_path); if(check_dir == 0) return 1; else return 0; } OBIDMS_column_directory_p obi_create_column_directory(OBIDMS_p dms, const char* column_name) { char* column_directory_name; int dms_file_descriptor; // Build and check the directory name column_directory_name = build_column_directory_name(column_name); if (column_directory_name == NULL) { obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); return NULL; } // Get the file descriptor for the dms dms_file_descriptor = dirfd(dms->directory); if (dms_file_descriptor < 0) { obi_set_errno(OBIDMS_UNKNOWN_ERROR); free(column_directory_name); return NULL; } // Try to create the directory if (private_mkdirat(dms_file_descriptor, column_directory_name, 0x777) < 0) { if (errno == EEXIST) obi_set_errno(OBICOLDIR_EXIST_ERROR); else obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); free(column_directory_name); close(dms_file_descriptor); return NULL; } free(column_directory_name); return obi_open_column_directory(dms, column_name); } OBIDMS_column_directory_p obi_open_column_directory(OBIDMS_p dms, const char* column_name) { OBIDMS_column_directory_p column_directory; char* column_directory_name; DIR* directory; int dms_file_descriptor; column_directory = NULL; // Build and check the directory name column_directory_name = build_column_directory_name(column_name); if (column_directory_name == NULL) return NULL; // Get the file descriptor for the dms dms_file_descriptor = dirfd(dms->directory); if (dms_file_descriptor < 0) { obi_set_errno(OBIDMS_UNKNOWN_ERROR); free(column_directory_name); return NULL; } // Try to open the column directory directory = private_opendirat(dms_file_descriptor, column_directory_name); if (directory == NULL) { switch (errno) { case ENOENT: obi_set_errno(OBICOLDIR_NOT_EXIST_ERROR); break; case EACCES: obi_set_errno(OBICOLDIR_ACCESS_ERROR); break; case ENOMEM: obi_set_errno(OBICOLDIR_MEMORY_ERROR); break; default: obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); } free(column_directory_name); close(dms_file_descriptor); return NULL; } // Allocate the column dir structure column_directory = (OBIDMS_column_directory_p) malloc(sizeof(OBIDMS_column_directory_t)); if (column_directory == NULL) { obi_set_errno(OBICOLDIR_MEMORY_ERROR); free(column_directory_name); close(dms_file_descriptor); return NULL; } // Initialize the data structure strcpy(column_directory->directory_name, column_directory_name); strcpy(column_directory->column_name, column_name); column_directory->directory = directory; free(column_directory_name); return column_directory; } OBIDMS_column_directory_p obi_column_directory(OBIDMS_p dms, const char* column_name) { int exists; exists = obi_column_directory_exists(dms, column_name); switch (exists) { case 0: return obi_create_column_directory(dms, column_name); case 1: return obi_open_column_directory(dms, column_name); }; return NULL; } int obi_close_column_directory(OBIDMS_column_directory_p column_directory) { if (column_directory != NULL) { // Close the column directory if (closedir(column_directory->directory) < 0) { obi_set_errno(OBICOLDIR_MEMORY_ERROR); free(column_directory); return -1; } free(column_directory); } return 0; }