1 /*********************************************************************
2   Blosc - Blocked Shuffling and Compression Library
3 
4   Copyright (C) 2021  The Blosc Developers <blosc@blosc.org>
5   https://blosc.org
6   License: BSD 3-Clause (see LICENSE.txt)
7 
8   See LICENSE.txt for details about copyright and rights to use.
9 **********************************************************************/
10 
11 #include <stdio.h>
12 #include "blosc2.h"
13 #include <sys/stat.h>
14 
15 #if defined(_WIN32)
16   #include <windows.h>
17   #include <malloc.h>
18   #include <io.h>
19 
blosc2_remove_dir(const char * dir_path)20   int blosc2_remove_dir(const char* dir_path) {
21     char* path;
22     char last_char = dir_path[strlen(dir_path) - 1];
23     if (last_char != '\\' || last_char != '/') {
24       path = malloc(strlen(dir_path) + 2 + 1);
25       sprintf(path, "%s\\*", dir_path);
26     }
27     else {
28       path = malloc(strlen(dir_path) + 1 + 1);
29       strcpy(path, dir_path);
30       strcat(path, "*");
31     }
32     char* fname;
33     struct _finddata_t cfile;
34 
35     intptr_t file = _findfirst(path, &cfile);
36     free(path);
37 
38     if (file == -1) {
39       BLOSC_TRACE_ERROR("Could not open the file.");
40       return BLOSC2_ERROR_FILE_OPEN;
41     }
42     int ret;
43 
44     while ( _findnext(file, &cfile) == 0) {
45       if (strcmp(".", cfile.name) == 0 || strcmp("..", cfile.name) == 0) {
46         continue;
47       }
48       fname = malloc(strlen(dir_path) + 1 + strlen(cfile.name) + 1);
49       sprintf(fname, "%s\\%s", dir_path, cfile.name);
50 
51       ret = remove(fname);
52       free(fname);
53       if (ret < 0) {
54         BLOSC_TRACE_ERROR("Could not remove file %s", fname);
55         _findclose(file);
56         return BLOSC2_ERROR_FAILURE;
57       }
58     }
59 
60     rmdir(dir_path);
61     _findclose(file);
62     return BLOSC2_ERROR_SUCCESS;
63   }
64 
65 #else
66   #include <dirent.h>
67   #include <unistd.h>
68 
69 /* Return the directory path with the '/' at the end */
blosc2_normalize_dirpath(const char * dir_path)70 char* blosc2_normalize_dirpath(const char* dir_path) {
71   char last_char = dir_path[strlen(dir_path) - 1];
72   char* path;
73   if (last_char != '\\' || last_char != '/'){
74     path = malloc(strlen(dir_path) + 1 + 1);
75     sprintf(path, "%s/", dir_path);
76   }
77   else {
78     path = malloc(strlen(dir_path) + 1);
79     strcpy(path, dir_path);
80   }
81   return path;
82 }
83 
84 /* Function needed for removing each time the directory */
blosc2_remove_dir(const char * dir_path)85 int blosc2_remove_dir(const char* dir_path) {
86   char* path = blosc2_normalize_dirpath(dir_path);
87 
88   DIR* dr = opendir(path);
89   struct stat statbuf;
90   if (dr == NULL) {
91     BLOSC_TRACE_ERROR("No file or directory found.");
92     free(path);
93     return BLOSC2_ERROR_NOT_FOUND;
94   }
95   struct dirent *de;
96   int ret;
97   char* fname;
98   while ((de = readdir(dr)) != NULL) {
99     fname = malloc(strlen(path) + strlen(de->d_name) + 1);
100     sprintf(fname, "%s%s", path, de->d_name);
101     if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
102       free(fname);
103       continue;
104     }
105     if (!stat(fname, &statbuf)) {
106       ret = unlink(fname);
107       if (ret < 0) {
108         BLOSC_TRACE_ERROR("Could not remove file %s", fname);
109         free(fname);
110         closedir(dr);
111         free(path);
112         return BLOSC2_ERROR_FAILURE;
113       }
114     }
115     free(fname);
116   }
117   closedir(dr);
118   rmdir(path);
119   free(path);
120   return BLOSC2_ERROR_SUCCESS;
121 }
122 
123 #endif  /* _WIN32 */
124 
blosc2_remove_urlpath(const char * urlpath)125 int blosc2_remove_urlpath(const char* urlpath){
126   if (urlpath != NULL) {
127     struct stat statbuf;
128     if (stat(urlpath, &statbuf) != 0){
129       BLOSC_TRACE_ERROR("Could not access %s", urlpath);
130       return BLOSC2_ERROR_FAILURE;
131     }
132     if ((statbuf.st_mode & S_IFDIR) != 0) {
133       return blosc2_remove_dir(urlpath);
134     }
135     if (remove(urlpath) < 0) {
136       BLOSC_TRACE_ERROR("Could not remove %s", urlpath);
137       return BLOSC2_ERROR_FILE_REMOVE;
138     }
139   }
140   return BLOSC2_ERROR_SUCCESS;
141 }
142 
blosc2_rename_urlpath(char * old_urlpath,char * new_urlpath)143 int blosc2_rename_urlpath(char* old_urlpath, char* new_urlpath){
144   if (old_urlpath != NULL && new_urlpath != NULL) {
145     struct stat statbuf;
146     if (stat(old_urlpath, &statbuf) != 0) {
147       BLOSC_TRACE_ERROR("Could not access %s", old_urlpath);
148       return BLOSC2_ERROR_FAILURE;
149     }
150     int ret = rename(old_urlpath, new_urlpath);
151     if (ret < 0) {
152       BLOSC_TRACE_ERROR("Could not rename %s to %s", old_urlpath, new_urlpath);
153       return BLOSC2_ERROR_FAILURE;
154     }
155   }
156   return BLOSC2_ERROR_SUCCESS;
157 }
158 
159