Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
pal_plat_fileSystem.c
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 *******************************************************************************/ 00016 00017 #include <sys/stat.h> 00018 #include <sys/types.h> 00019 #include <sys/mount.h> 00020 #include <errno.h> 00021 #include <stdio.h> 00022 #include <unistd.h> 00023 #include <string.h> 00024 #include <dirent.h> 00025 #include <stdlib.h> 00026 00027 //PAL Includes 00028 #include "pal.h" 00029 #include "pal_plat_fileSystem.h" 00030 #include "pal_plat_rtos.h" 00031 00032 00033 #define PAL_FS_COPY_BUFFER_SIZE 256 //!< Size of the chunk to copy files 00034 00035 PAL_PRIVATE const char* g_platOpenModeConvert[] = {"0", "r", "r+", "w+x", "w+"}; //!< platform convert table for \b fopen() modes 00036 PAL_PRIVATE const int g_platSeekWhenceConvert[] = {0, SEEK_SET, SEEK_CUR, SEEK_END}; //!< platform convert table for \b fseek() relative position modes 00037 00038 00039 00040 /*! \brief This function find the next file in a directory 00041 * 00042 * @param[in] *dh - Directory handler to an open DIR 00043 * @param[out] CurrentEntry - entry for the file found in Directory (pre allocated) 00044 * 00045 * \return true - upon successful operation.\n 00046 * 00047 */ 00048 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry); 00049 00050 /*! \brief This function translate the platform errors opcode to pal error codes 00051 * 00052 * @param[in] errorOpCode - platform opcode to be translated 00053 * 00054 * \return PAL_SUCCESS upon successful operation.\n 00055 */ 00056 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode); 00057 00058 00059 /*! \brief This function build the full path name by adding the filename to the working path given in pathName arg 00060 * 00061 * @param[in] *pathName - pointer to the null-terminated string that specifies the directory name. 00062 * @param[in] *fileName - pointer to the file name 00063 * @param[out] *fullPath - pointer to the full path including the filename (pre allocated) 00064 * @param[in] fullPathSize - size of fullPath 00065 * 00066 * \return PAL_SUCCESS upon successful operation.\n 00067 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00068 * 00069 */ 00070 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath, size_t fullPathSize); 00071 00072 /*! \brief This function copy one file from source folder to destination folder 00073 * 00074 * @param[in] pathNameSrc - Pointer to a null-terminated string that specifies the source dir. 00075 * @param[in] pathNameDest - Pointer to a null-terminated string that specifies the destination dir 00076 * @param[in] fileName - pointer the the file name 00077 * 00078 * \return PAL_SUCCESS upon successful operation.\n 00079 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00080 * 00081 * \note File should not be open.\n 00082 * If the Destination file exist then it shall be truncated 00083 * 00084 */ 00085 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName); 00086 00087 palStatus_t pal_plat_fsMkdir(const char *pathName) 00088 { 00089 palStatus_t ret = PAL_SUCCESS; 00090 int platStatus = 0; 00091 00092 platStatus = mkdir(pathName, 0777); 00093 if (platStatus) 00094 { 00095 ret = pal_plat_errorTranslation(errno); 00096 } 00097 return ret; 00098 } 00099 00100 00101 palStatus_t pal_plat_fsRmdir(const char *pathName) 00102 { 00103 palStatus_t ret = PAL_SUCCESS; 00104 00105 if (rmdir(pathName)) 00106 { 00107 if(errno == ENOENT) 00108 { 00109 ret = PAL_ERR_FS_NO_PATH; 00110 } 00111 else 00112 { 00113 ret = pal_plat_errorTranslation(errno); 00114 } 00115 } 00116 return ret; 00117 } 00118 00119 00120 palStatus_t pal_plat_fsFopen(const char *pathName, pal_fsFileMode_t mode, palFileDescriptor_t *fd) 00121 { 00122 palStatus_t ret = PAL_SUCCESS; 00123 00124 *fd = (palFileDescriptor_t)fopen(pathName, g_platOpenModeConvert[mode]); 00125 if ((*fd) == NULLPTR) 00126 { 00127 ret = pal_plat_errorTranslation(errno); 00128 } 00129 return ret; 00130 } 00131 00132 00133 palStatus_t pal_plat_fsFclose(palFileDescriptor_t *fd) 00134 { 00135 palStatus_t ret = PAL_SUCCESS; 00136 if (fclose((FILE *)*fd)) 00137 { 00138 ret = pal_plat_errorTranslation(errno); 00139 } 00140 00141 return ret; 00142 } 00143 00144 00145 palStatus_t pal_plat_fsFread(palFileDescriptor_t *fd, void * buffer, size_t numOfBytes, size_t *numberOfBytesRead) 00146 { 00147 palStatus_t ret = PAL_SUCCESS; 00148 *numberOfBytesRead = fread(buffer, 1, numOfBytes, (FILE *)*fd); 00149 if (*numberOfBytesRead != numOfBytes) 00150 { 00151 if (ferror((FILE *)*fd)) 00152 { 00153 ret = PAL_ERR_FS_ERROR; 00154 } 00155 clearerr((FILE *)*fd); 00156 } 00157 return ret; 00158 } 00159 00160 00161 palStatus_t pal_plat_fsFwrite(palFileDescriptor_t *fd, const void *buffer, size_t numOfBytes, size_t *numberOfBytesWritten) 00162 { 00163 palStatus_t ret = PAL_SUCCESS; 00164 *numberOfBytesWritten = fwrite(buffer, 1, numOfBytes, (FILE *)*fd); 00165 errno = 0; 00166 if (*numberOfBytesWritten != numOfBytes) 00167 { 00168 ret = pal_plat_errorTranslation(errno); 00169 if(ret == PAL_SUCCESS) 00170 { 00171 ret = PAL_ERR_FS_ACCESS_DENIED; 00172 } 00173 } 00174 return ret; 00175 } 00176 00177 00178 palStatus_t pal_plat_fsFseek(palFileDescriptor_t *fd, int32_t offset, pal_fsOffset_t whence) 00179 { 00180 palStatus_t ret = PAL_SUCCESS; 00181 if (fseek((FILE *)*fd, offset, g_platSeekWhenceConvert[whence])) 00182 { 00183 ret = pal_plat_errorTranslation(errno); 00184 } 00185 return ret; 00186 } 00187 00188 00189 palStatus_t pal_plat_fsFtell(palFileDescriptor_t *fd, int32_t * pos) 00190 { 00191 palStatus_t ret = PAL_SUCCESS; 00192 long retPos = 0; 00193 *pos = 0; 00194 retPos = ftell((FILE *)*fd); 00195 if (retPos < 0) 00196 { 00197 ret = pal_plat_errorTranslation(errno); 00198 } 00199 else 00200 { 00201 *pos = retPos; 00202 } 00203 return ret; 00204 } 00205 00206 00207 palStatus_t pal_plat_fsUnlink(const char *pathName) 00208 { 00209 palStatus_t ret = PAL_SUCCESS; 00210 00211 if (unlink(pathName)) 00212 { 00213 ret = pal_plat_errorTranslation(errno); 00214 } 00215 return ret; 00216 } 00217 00218 00219 palStatus_t pal_plat_fsRmFiles(const char *pathName) 00220 { 00221 DIR *dh = NULL; //Directory handler 00222 palStatus_t ret = PAL_SUCCESS; 00223 char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00224 struct dirent * currentEntry = NULL; //file Entry 00225 00226 00227 dh = opendir(pathName); 00228 00229 if (dh) 00230 { 00231 while(true) 00232 { 00233 if (!pal_plat_findNextFile(dh, ¤tEntry)) 00234 { 00235 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00236 break; 00237 } 00238 if (currentEntry) 00239 { 00240 pal_plat_addFileNameToPath(pathName, currentEntry->d_name, buffer, sizeof(buffer)); 00241 if (currentEntry->d_type == DT_DIR) 00242 { 00243 pal_fsRmFiles(buffer); 00244 if (rmdir(buffer)) 00245 { 00246 ret = pal_plat_errorTranslation(errno); 00247 break; 00248 } 00249 } 00250 else 00251 { 00252 if (unlink(buffer)) 00253 { 00254 ret = pal_plat_errorTranslation(errno); 00255 break; 00256 } 00257 } 00258 } 00259 else 00260 {//End of directory reached without errors break, close directory and exit 00261 break; 00262 } 00263 }//while() 00264 } 00265 else//if (dh) 00266 { 00267 ret = PAL_ERR_FS_NO_PATH; 00268 } 00269 00270 if (dh) 00271 { 00272 closedir(dh); //Close DIR handler 00273 } 00274 return ret; 00275 } 00276 00277 00278 palStatus_t pal_plat_fsCpFolder(const char *pathNameSrc, char *pathNameDest) 00279 { 00280 DIR *src_dh = NULL; //Directory for the source Directory handler 00281 palStatus_t ret = PAL_SUCCESS; 00282 struct dirent * currentEntry = NULL; //file Entry 00283 00284 00285 src_dh = opendir(pathNameSrc); 00286 if (src_dh == NULL) 00287 { 00288 ret = PAL_ERR_FS_NO_PATH; 00289 } 00290 else 00291 { 00292 while(true) 00293 { 00294 if (!pal_plat_findNextFile(src_dh, ¤tEntry)) 00295 { 00296 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00297 break; 00298 } 00299 if (currentEntry) 00300 { 00301 if (currentEntry->d_type == DT_DIR) 00302 { 00303 continue; 00304 } 00305 //copy the file to the destination 00306 ret = pal_plat_fsCpFile(pathNameSrc, pathNameDest, currentEntry->d_name); 00307 if (ret != PAL_SUCCESS) 00308 { 00309 break; 00310 } 00311 } 00312 else 00313 {//End of directory reached without errors break and close directory and exit 00314 break; 00315 } 00316 }//while() 00317 } 00318 00319 if (src_dh) 00320 { 00321 closedir(src_dh); 00322 } 00323 return ret; 00324 } 00325 00326 00327 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName) 00328 { 00329 palStatus_t ret = PAL_SUCCESS; 00330 palFileDescriptor_t src_fd = 0; 00331 palFileDescriptor_t dst_fd = 0; 00332 char buffer_name[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00333 char * buffer = NULL; 00334 size_t bytesCount = 0; 00335 00336 //Add file name to path 00337 pal_plat_addFileNameToPath(pathNameSrc, fileName, buffer_name, sizeof(buffer_name)); 00338 src_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READONLY]); 00339 if (src_fd == 0) 00340 { 00341 ret = pal_plat_errorTranslation(errno); 00342 } 00343 else 00344 { 00345 //Add file name to path 00346 pal_plat_addFileNameToPath(pathNameDest, fileName, buffer_name, sizeof(buffer_name)); 00347 dst_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READWRITETRUNC]); 00348 if (dst_fd == 0) 00349 { 00350 ret = pal_plat_errorTranslation(errno); 00351 } 00352 else 00353 { 00354 buffer = (char*)pal_plat_malloc (PAL_FS_COPY_BUFFER_SIZE); 00355 if (!buffer) 00356 { 00357 ret = PAL_ERR_RTOS_RESOURCE ; 00358 } 00359 } 00360 } 00361 00362 if (ret == PAL_SUCCESS) 00363 { 00364 while (1) 00365 { 00366 ret = pal_fsFread(&src_fd, buffer, PAL_FS_COPY_BUFFER_SIZE, &bytesCount); 00367 if (ret != PAL_SUCCESS) 00368 { 00369 break; 00370 } 00371 00372 //Check if end of file reached 00373 if (bytesCount == 0) 00374 { 00375 break; 00376 } 00377 00378 ret = pal_fsFwrite(&dst_fd, buffer, bytesCount, &bytesCount); 00379 if (ret != PAL_SUCCESS) 00380 { 00381 break; 00382 } 00383 } 00384 } 00385 00386 if (src_fd != 0) 00387 { 00388 pal_fsFclose(&src_fd); 00389 } 00390 if (dst_fd != 0) 00391 { 00392 pal_fsFclose(&dst_fd); 00393 } 00394 if (buffer) 00395 { 00396 pal_plat_free (buffer); 00397 } 00398 return ret; 00399 } 00400 00401 00402 const char* pal_plat_fsGetDefaultRootFolder(pal_fsStorageID_t dataID) 00403 { 00404 const char* returnedRoot = NULL; 00405 if (PAL_FS_PARTITION_PRIMARY == dataID) 00406 { 00407 returnedRoot = PAL_FS_MOUNT_POINT_PRIMARY; 00408 } 00409 else if (PAL_FS_PARTITION_SECONDARY == dataID) 00410 { 00411 returnedRoot = PAL_FS_MOUNT_POINT_SECONDARY; 00412 } 00413 00414 return returnedRoot; 00415 } 00416 00417 00418 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry) 00419 { 00420 bool ret = true; 00421 bool skip = false; 00422 bool foundFile = false; 00423 00424 do 00425 { 00426 errno = 0; 00427 *CurrentEntry = readdir(dh); 00428 if (*CurrentEntry) 00429 { 00430 /* Skip the names "." and ".." as we don't want to remove them. also make sure that the current entry point to REGULER file*/ 00431 skip = (!strcmp((*CurrentEntry)->d_name, ".")) || (!strcmp((*CurrentEntry)->d_name, "..")); 00432 if (skip) 00433 { 00434 continue; 00435 } 00436 else 00437 { 00438 foundFile = true; 00439 } 00440 } 00441 else 00442 {//Check if EOF reached 00443 if (errno) 00444 {//NOT!!! EOF other error 00445 ret = false; 00446 } 00447 break; //Break from while 00448 } 00449 } 00450 while((!foundFile) && (ret)); //While file has been found or ret is set to false 00451 return ret; 00452 } 00453 00454 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath, size_t fullPathSize) 00455 { 00456 palStatus_t ret = PAL_SUCCESS; 00457 if ((strlen(pathName) >= PAL_MAX_FOLDER_DEPTH_CHAR) || (strlen(fileName) >= PAL_MAX_FULL_FILE_NAME)) 00458 { 00459 ret = PAL_ERR_FS_FILENAME_LENGTH; 00460 } 00461 else if (fullPath) 00462 { 00463 strncpy(fullPath, pathName, fullPathSize - 1); 00464 fullPath[fullPathSize - 1] = '\0'; 00465 strncat(fullPath, "/", fullPathSize - strlen(fullPath) - 1); 00466 strncat(fullPath, fileName, fullPathSize - strlen(fullPath) - 1); 00467 } 00468 else 00469 { 00470 ret = PAL_ERR_RTOS_RESOURCE ; 00471 } 00472 return ret; 00473 } 00474 00475 00476 00477 00478 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode) 00479 { 00480 palStatus_t ret = PAL_SUCCESS; 00481 00482 switch(errorOpCode) 00483 { 00484 case 0: 00485 break; 00486 case EACCES: 00487 case EFAULT: 00488 case EROFS: 00489 ret = PAL_ERR_FS_ACCESS_DENIED; 00490 break; 00491 00492 case EBUSY : 00493 ret = PAL_ERR_FS_BUSY; 00494 break; 00495 00496 case EEXIST: 00497 ret = PAL_ERR_FS_NAME_ALREADY_EXIST; 00498 break; 00499 00500 case ENAMETOOLONG: 00501 ret = PAL_ERR_FS_FILENAME_LENGTH; 00502 break; 00503 00504 case EBADF: 00505 ret = PAL_ERR_FS_BAD_FD; 00506 break; 00507 00508 case EINVAL: 00509 ret = PAL_ERR_FS_INVALID_ARGUMENT; 00510 break; 00511 00512 case EISDIR: 00513 ret = PAL_ERR_FS_FILE_IS_DIR; 00514 break; 00515 00516 case ENOTEMPTY: 00517 ret = PAL_ERR_FS_DIR_NOT_EMPTY; 00518 break; 00519 00520 case ENOENT: 00521 ret = PAL_ERR_FS_NO_FILE; 00522 break; 00523 00524 default: 00525 ret = PAL_ERR_FS_ERROR; 00526 break; 00527 } 00528 return ret; 00529 } 00530 00531 00532 size_t pal_plat_fsSizeCheck(const char *stringToChk) 00533 { 00534 size_t length = 0; 00535 length = strlen(stringToChk); 00536 return length; 00537 } 00538 00539 00540 palStatus_t pal_plat_fsFormat(pal_fsStorageID_t dataID) 00541 { 00542 char rootFolder[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; 00543 palStatus_t result = PAL_SUCCESS; 00544 result = pal_fsGetMountPoint(dataID, PAL_MAX_FILE_AND_FOLDER_LENGTH, rootFolder); 00545 if (PAL_SUCCESS == result) 00546 { 00547 int ret; 00548 FILE* fp = NULL; 00549 char buffer[PAL_FORMAT_CMD_MAX_LENGTH] = {0}; 00550 char deviceName[PAL_DEVICE_NAME_MAX_LENGTH] = {0}; 00551 00552 ret = snprintf(buffer, sizeof(buffer),"df -h | grep %s | awk -F\' \' \'{print $1}\' 2>&1",rootFolder); // get the partition name or the error 00553 PAL_LOG(DBG,"system call command is %s ret = %d\r\n",buffer,ret); 00554 if (ret > 0) // snprintf succeeded 00555 { 00556 fp = popen(buffer,"r"); 00557 if (NULL != fp) 00558 { 00559 if(NULL != fgets(deviceName, sizeof(deviceName),fp)) 00560 { 00561 if (deviceName[strnlen(deviceName, sizeof(deviceName))-1] == '\n') 00562 { 00563 deviceName[strnlen(deviceName, sizeof(deviceName))-1] = '\0'; // remove the '\n' if found 00564 } 00565 ret = umount(rootFolder); 00566 if (0 == ret) 00567 { 00568 ret = snprintf(buffer, sizeof(buffer), PAL_FS_FORMAT_COMMAND, PAL_PARTITION_FORMAT_TYPE, deviceName); 00569 if (ret > 0) 00570 { 00571 ret = system(buffer); 00572 if (-1 != ret) 00573 { 00574 ret = mount(deviceName, rootFolder, PAL_PARTITION_FORMAT_TYPE, 0 ,PARTITION_FORMAT_ADDITIONAL_PARAMS); 00575 if (ret < 0) 00576 { 00577 PAL_LOG(ERR,"(%s:%d)cannot mount %s on %s using " PAL_PARTITION_FORMAT_TYPE,__FILE__,__LINE__,deviceName,rootFolder); 00578 result = PAL_ERR_GENERIC_FAILURE; 00579 } 00580 } 00581 else 00582 { 00583 PAL_LOG(ERR,"(%s:%d)system call to format failed ",__FILE__,__LINE__); 00584 result = PAL_ERR_SYSCALL_FAILED ; 00585 } 00586 } 00587 else 00588 { 00589 PAL_LOG(ERR,"(%s:%d)cannot create command with snprintf ",__FILE__,__LINE__); 00590 result = PAL_ERR_BUFFER_TOO_SMALL ; 00591 } 00592 } 00593 else 00594 { 00595 PAL_LOG(ERR,"(%s:%d)cannot unmount %s",__FILE__,__LINE__,rootFolder); 00596 result = PAL_ERR_GENERIC_FAILURE; 00597 } 00598 } 00599 00600 else 00601 { 00602 PAL_LOG(ERR,"(%s:%d)cannot read from pipe",__FILE__,__LINE__); 00603 result = PAL_ERR_GENERIC_FAILURE; 00604 } 00605 pclose(fp); 00606 } 00607 else 00608 { 00609 PAL_LOG(ERR,"(%s:%d)popen had failed ",__FILE__,__LINE__); 00610 result = PAL_ERR_SYSCALL_FAILED ; 00611 } 00612 } 00613 else 00614 { 00615 PAL_LOG(ERR,"(%s:%d)cannot create command with snprintf ",__FILE__,__LINE__); 00616 result = PAL_ERR_BUFFER_TOO_SMALL ; 00617 } 00618 } 00619 return result; 00620 } 00621
Generated on Tue Jul 12 2022 19:12:14 by 1.7.2