osDir.c 8.3 KB
Newer Older
S
Shengliang Guan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

L
Liu Jicong 已提交
16
#define _DEFAULT_SOURCE
wafwerar's avatar
wafwerar 已提交
17
#define ALLOW_FORBID_FUNC
L
Liu Jicong 已提交
18

S
Shengliang Guan 已提交
19
#include "os.h"
S
TD-1574  
Shengliang Guan 已提交
20

wafwerar's avatar
wafwerar 已提交
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#ifdef WINDOWS

#include <windows.h>

typedef struct TdDirEntry {
  WIN32_FIND_DATA findFileData;
} TdDirEntry;

typedef struct TdDir {
  TdDirEntry dirEntry;
  HANDLE     hFind;
} TdDir;

int wordexp(char *words, wordexp_t *pwordexp, int flags) {
  pwordexp->we_offs = 0;
  pwordexp->we_wordc = 1;
  pwordexp->we_wordv[0] = pwordexp->wordPos;

  memset(pwordexp->wordPos, 0, 1025);
  if (_fullpath(pwordexp->wordPos, words, 1024) == NULL) {
    pwordexp->we_wordv[0] = words;
wafwerar's avatar
wafwerar 已提交
42
    printf("failed to parse relative path:%s to abs path\n", words);
wafwerar's avatar
wafwerar 已提交
43 44 45
    return -1;
  }

wafwerar's avatar
wafwerar 已提交
46
  // printf("parse relative path:%s to abs path:%s\n", words, pwordexp->wordPos);
wafwerar's avatar
wafwerar 已提交
47 48
  return 0;
}
S
Shengliang Guan 已提交
49

wafwerar's avatar
wafwerar 已提交
50
void wordfree(wordexp_t *pwordexp) {}
S
Shengliang Guan 已提交
51 52

#else
S
Shengliang Guan 已提交
53

S
Shengliang Guan 已提交
54 55 56 57 58 59
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wordexp.h>

wafwerar's avatar
wafwerar 已提交
60
typedef struct dirent dirent;
dengyihao's avatar
dengyihao 已提交
61
typedef struct DIR    TdDir;
wafwerar's avatar
wafwerar 已提交
62 63 64
typedef struct dirent TdDirEntry;

#endif
wafwerar's avatar
wafwerar 已提交
65

H
Hongze Cheng 已提交
66
void taosRemoveDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
67 68
  TdDirPtr pDir = taosOpenDir(dirname);
  if (pDir == NULL) return;
S
Shengliang Guan 已提交
69

wafwerar's avatar
wafwerar 已提交
70 71 72
  TdDirEntryPtr de = NULL;
  while ((de = taosReadDir(pDir)) != NULL) {
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
S
TD-4088  
Shengliang Guan 已提交
73

S
Shengliang Guan 已提交
74 75
    char filename[1024] = {0};
    snprintf(filename, sizeof(filename), "%s%s%s", dirname, TD_DIRSEP, taosGetDirEntryName(de));
wafwerar's avatar
wafwerar 已提交
76
    if (taosDirEntryIsDir(de)) {
S
Shengliang Guan 已提交
77 78
      taosRemoveDir(filename);
    } else {
79
      (void)taosRemoveFile(filename);
dengyihao's avatar
dengyihao 已提交
80
      // printf("file:%s is removed\n", filename);
S
Shengliang Guan 已提交
81 82 83
    }
  }

wafwerar's avatar
wafwerar 已提交
84
  taosCloseDir(&pDir);
S
Shengliang Guan 已提交
85
  rmdir(dirname);
S
Shengliang Guan 已提交
86

dengyihao's avatar
dengyihao 已提交
87
  // printf("dir:%s is removed\n", dirname);
wafwerar's avatar
wafwerar 已提交
88
  return;
S
Shengliang Guan 已提交
89 90
}

wafwerar's avatar
wafwerar 已提交
91
bool taosDirExist(const char *dirname) { return taosCheckExistFile(dirname); }
92

93
int32_t taosMkDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
94 95 96 97
  if (taosDirExist(dirname)) return 0;
#ifdef WINDOWS
  int32_t code = _mkdir(dirname, 0755);
#else
wafwerar's avatar
wafwerar 已提交
98
  int32_t code = mkdir(dirname, 0755);
wafwerar's avatar
wafwerar 已提交
99
#endif
wafwerar's avatar
wafwerar 已提交
100 101 102 103 104 105 106 107
  if (code < 0 && errno == EEXIST) {
    return 0;
  }

  return code;
}

int32_t taosMulMkDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
108
  if (dirname == NULL) return -1;
wafwerar's avatar
wafwerar 已提交
109
  char temp[1024];
wafwerar's avatar
wafwerar 已提交
110 111
  char *  pos = temp;
  int32_t code = 0;
wafwerar's avatar
wafwerar 已提交
112 113
#ifdef WINDOWS
  taosRealPath(dirname, temp, sizeof(temp));
wafwerar's avatar
wafwerar 已提交
114
  if (temp[1] == ':') pos += 3;
wafwerar's avatar
wafwerar 已提交
115 116 117
#else
  strcpy(temp, dirname);
#endif
wafwerar's avatar
wafwerar 已提交
118

wafwerar's avatar
wafwerar 已提交
119 120 121
  if (taosDirExist(temp)) return code;

  if (strncmp(temp, TD_DIRSEP, 1) == 0) {
wafwerar's avatar
wafwerar 已提交
122
    pos += 1;
wafwerar's avatar
wafwerar 已提交
123
  } else if (strncmp(temp, "." TD_DIRSEP, 2) == 0) {
wafwerar's avatar
wafwerar 已提交
124 125
    pos += 2;
  }
dengyihao's avatar
dengyihao 已提交
126 127

  for (; *pos != '\0'; pos++) {
wafwerar's avatar
wafwerar 已提交
128
    if (*pos == TD_DIRSEP[0]) {
wafwerar's avatar
wafwerar 已提交
129
      *pos = '\0';
wafwerar's avatar
wafwerar 已提交
130 131 132
    #ifdef WINDOWS
      code = _mkdir(temp, 0755);
    #else
wafwerar's avatar
wafwerar 已提交
133
      code = mkdir(temp, 0755);
wafwerar's avatar
wafwerar 已提交
134
    #endif
wafwerar's avatar
wafwerar 已提交
135 136 137
      if (code < 0 && errno != EEXIST) {
        return code;
      }
wafwerar's avatar
wafwerar 已提交
138
      *pos = TD_DIRSEP[0];
wafwerar's avatar
wafwerar 已提交
139 140
    }
  }
dengyihao's avatar
dengyihao 已提交
141

wafwerar's avatar
wafwerar 已提交
142 143 144 145
  if (*(pos - 1) != TD_DIRSEP[0]) {
  #ifdef WINDOWS
    code = _mkdir(temp, 0755);
  #else
wafwerar's avatar
wafwerar 已提交
146
    code = mkdir(temp, 0755);
wafwerar's avatar
wafwerar 已提交
147
  #endif
wafwerar's avatar
wafwerar 已提交
148 149 150 151 152 153
    if (code < 0 && errno != EEXIST) {
      return code;
    }
  }

  // int32_t code = mkdir(dirname, 0755);
S
Shengliang Guan 已提交
154
  if (code < 0 && errno == EEXIST) {
155
    return 0;
S
Shengliang Guan 已提交
156 157
  }

158
  return code;
S
Shengliang Guan 已提交
159 160
}

S
config  
Shengliang Guan 已提交
161
void taosRemoveOldFiles(const char *dirname, int32_t keepDays) {
wafwerar's avatar
wafwerar 已提交
162 163
  TdDirPtr pDir = taosOpenDir(dirname);
  if (pDir == NULL) return;
S
TD-1263  
Shengliang Guan 已提交
164

dengyihao's avatar
dengyihao 已提交
165
  int64_t       sec = taosGetTimestampSec();
wafwerar's avatar
wafwerar 已提交
166
  TdDirEntryPtr de = NULL;
S
TD-1263  
Shengliang Guan 已提交
167

wafwerar's avatar
wafwerar 已提交
168 169
  while ((de = taosReadDir(pDir)) != NULL) {
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
S
TD-1263  
Shengliang Guan 已提交
170 171

    char filename[1024];
wafwerar's avatar
wafwerar 已提交
172 173
    snprintf(filename, sizeof(filename), "%s/%s", dirname, taosGetDirEntryName(de));
    if (taosDirEntryIsDir(de)) {
S
TD-1263  
Shengliang Guan 已提交
174 175
      continue;
    } else {
S
Shengliang Guan 已提交
176
      int32_t len = (int32_t)strlen(filename);
S
TD-1574  
Shengliang Guan 已提交
177 178 179 180
      if (len > 3 && strcmp(filename + len - 3, ".gz") == 0) {
        len -= 3;
      }

S
TD-1263  
Shengliang Guan 已提交
181
      int64_t fileSec = 0;
S
Shengliang Guan 已提交
182
      for (int32_t i = len - 1; i >= 0; i--) {
S
TD-1263  
Shengliang Guan 已提交
183
        if (filename[i] == '.') {
S
TD-1263  
Shengliang Guan 已提交
184
          fileSec = atoll(filename + i + 1);
S
TD-1263  
Shengliang Guan 已提交
185 186 187 188
          break;
        }
      }

S
TD-1263  
Shengliang Guan 已提交
189
      if (fileSec <= 100) continue;
dengyihao's avatar
dengyihao 已提交
190
      int32_t days = (int32_t)(TABS(sec - fileSec) / 86400 + 1);
S
TD-1263  
Shengliang Guan 已提交
191
      if (days > keepDays) {
192
        (void)taosRemoveFile(filename);
dengyihao's avatar
dengyihao 已提交
193
        // printf("file:%s is removed, days:%d keepDays:%d", filename, days, keepDays);
S
TD-1263  
Shengliang Guan 已提交
194
      } else {
dengyihao's avatar
dengyihao 已提交
195
        // printf("file:%s won't be removed, days:%d keepDays:%d", filename, days, keepDays);
S
TD-1263  
Shengliang Guan 已提交
196 197 198 199
      }
    }
  }

wafwerar's avatar
wafwerar 已提交
200
  taosCloseDir(&pDir);
S
Shengliang Guan 已提交
201
  rmdir(dirname);
S
TD-1263  
Shengliang Guan 已提交
202
}
S
TD-1574  
Shengliang Guan 已提交
203

S
config  
Shengliang Guan 已提交
204
int32_t taosExpandDir(const char *dirname, char *outname, int32_t maxlen) {
S
Shengliang Guan 已提交
205 206
  wordexp_t full_path;
  if (0 != wordexp(dirname, &full_path, 0)) {
wafwerar's avatar
wafwerar 已提交
207
    printf("failed to expand path:%s since %s", dirname, strerror(errno));
S
Shengliang Guan 已提交
208
    wordfree(&full_path);
209
    return -1;
S
TD-1574  
Shengliang Guan 已提交
210 211
  }

S
Shengliang Guan 已提交
212 213
  if (full_path.we_wordv != NULL && full_path.we_wordv[0] != NULL) {
    strncpy(outname, full_path.we_wordv[0], maxlen);
S
TD-1574  
Shengliang Guan 已提交
214 215
  }

S
Shengliang Guan 已提交
216
  wordfree(&full_path);
S
TD-1574  
Shengliang Guan 已提交
217

218
  return 0;
S
Shengliang Guan 已提交
219
}
S
TD-1574  
Shengliang Guan 已提交
220

wafwerar's avatar
wafwerar 已提交
221
int32_t taosRealPath(char *dirname, char *realPath, int32_t maxlen) {
S
Shengliang Guan 已提交
222
  char tmp[PATH_MAX] = {0};
wafwerar's avatar
wafwerar 已提交
223
#ifdef WINDOWS
wafwerar's avatar
wafwerar 已提交
224
  if (_fullpath(tmp, dirname, maxlen) != NULL) {
wafwerar's avatar
wafwerar 已提交
225
#else
S
Shengliang Guan 已提交
226
  if (realpath(dirname, tmp) != NULL) {
wafwerar's avatar
wafwerar 已提交
227 228 229 230 231 232 233
#endif
    if (realPath == NULL) {
      strncpy(dirname, tmp, maxlen);
    } else {
      strncpy(realPath, tmp, maxlen);
    }
    return 0;
S
TD-1574  
Shengliang Guan 已提交
234 235
  }

wafwerar's avatar
wafwerar 已提交
236
  return -1;
S
TD-1574  
Shengliang Guan 已提交
237
}
S
Shengliang Guan 已提交
238

239
bool taosIsDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
240 241 242
  TdDirPtr pDir = taosOpenDir(dirname);
  if (pDir != NULL) {
    taosCloseDir(&pDir);
243 244 245 246 247
    return true;
  }
  return false;
}

dengyihao's avatar
dengyihao 已提交
248
char *taosDirName(char *name) {
wafwerar's avatar
wafwerar 已提交
249
#ifdef WINDOWS
dengyihao's avatar
dengyihao 已提交
250
  char Drive1[MAX_PATH], Dir1[MAX_PATH];
wafwerar's avatar
wafwerar 已提交
251 252 253
  _splitpath(name, Drive1, Dir1, NULL, NULL);
  size_t dirNameLen = strlen(Drive1) + strlen(Dir1);
  if (dirNameLen > 0) {
wafwerar's avatar
wafwerar 已提交
254 255 256 257 258 259 260
    if (name[dirNameLen - 1] == '/' || name[dirNameLen - 1] == '\\') {
      name[dirNameLen - 1] = 0;
    } else {
      name[dirNameLen] = 0;
    }
  } else {
    name[0] = 0;
wafwerar's avatar
wafwerar 已提交
261 262
  }
  return name;
wafwerar's avatar
wafwerar 已提交
263 264 265 266 267 268 269 270
#elif defined(_TD_DARWIN_64)
  char *end = strrchr(name, '/');
  if (end != NULL) {
    *end = '\0';
  } else {
    name[0] = 0;
  }
  return name; 
wafwerar's avatar
wafwerar 已提交
271
#else
wafwerar's avatar
wafwerar 已提交
272
  return dirname(name);
wafwerar's avatar
wafwerar 已提交
273
#endif
wafwerar's avatar
wafwerar 已提交
274 275
}

dengyihao's avatar
dengyihao 已提交
276
char *taosDirEntryBaseName(char *name) {
wafwerar's avatar
wafwerar 已提交
277 278 279 280 281
#ifdef WINDOWS
  char Filename1[MAX_PATH], Ext1[MAX_PATH];
  _splitpath(name, NULL, NULL, Filename1, Ext1);
  return name + (strlen(name) - strlen(Filename1) - strlen(Ext1));
#else
dengyihao's avatar
dengyihao 已提交
282
  return (char *)basename(name);
wafwerar's avatar
wafwerar 已提交
283
#endif
wafwerar's avatar
wafwerar 已提交
284 285 286 287 288 289
}

TdDirPtr taosOpenDir(const char *dirname) {
  if (dirname == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
290 291

#ifdef WINDOWS
dengyihao's avatar
dengyihao 已提交
292 293
  char   szFind[MAX_PATH];  //这是要找的
  HANDLE hFind;
wafwerar's avatar
wafwerar 已提交
294 295 296 297 298 299 300 301 302 303 304 305 306

  TdDirPtr pDir = taosMemoryMalloc(sizeof(TdDir));

  strcpy(szFind, dirname);
  strcat(szFind, "\\*.*");  //利用通配符找这个目录下的所以文件,包括目录

  pDir->hFind = FindFirstFile(szFind, &(pDir->dirEntry.findFileData));
  if (INVALID_HANDLE_VALUE == pDir->hFind) {
    taosMemoryFree(pDir);
    return NULL;
  }
  return pDir;
#else
wafwerar's avatar
wafwerar 已提交
307
  return (TdDirPtr)opendir(dirname);
wafwerar's avatar
wafwerar 已提交
308
#endif
wafwerar's avatar
wafwerar 已提交
309 310 311 312 313 314
}

TdDirEntryPtr taosReadDir(TdDirPtr pDir) {
  if (pDir == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
315 316 317 318
#ifdef WINDOWS
  if (!FindNextFile(pDir->hFind, &(pDir->dirEntry.findFileData))) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
319
  return (TdDirEntryPtr) & (pDir->dirEntry.findFileData);
wafwerar's avatar
wafwerar 已提交
320
#else
dengyihao's avatar
dengyihao 已提交
321
  return (TdDirEntryPtr)readdir((DIR *)pDir);
wafwerar's avatar
wafwerar 已提交
322
#endif
wafwerar's avatar
wafwerar 已提交
323 324 325 326 327 328
}

bool taosDirEntryIsDir(TdDirEntryPtr pDirEntry) {
  if (pDirEntry == NULL) {
    return false;
  }
wafwerar's avatar
wafwerar 已提交
329 330 331
#ifdef WINDOWS
  return (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
dengyihao's avatar
dengyihao 已提交
332
  return (((dirent *)pDirEntry)->d_type & DT_DIR) != 0;
wafwerar's avatar
wafwerar 已提交
333
#endif
wafwerar's avatar
wafwerar 已提交
334 335
}

dengyihao's avatar
dengyihao 已提交
336
char *taosGetDirEntryName(TdDirEntryPtr pDirEntry) {
wafwerar's avatar
wafwerar 已提交
337 338 339
  if (pDirEntry == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
340 341 342
#ifdef WINDOWS
  return pDirEntry->findFileData.cFileName;
#else
dengyihao's avatar
dengyihao 已提交
343
  return ((dirent *)pDirEntry)->d_name;
wafwerar's avatar
wafwerar 已提交
344
#endif
wafwerar's avatar
wafwerar 已提交
345 346
}

wafwerar's avatar
wafwerar 已提交
347 348
int32_t taosCloseDir(TdDirPtr *ppDir) {
  if (ppDir == NULL || *ppDir == NULL) {
wafwerar's avatar
wafwerar 已提交
349 350
    return -1;
  }
wafwerar's avatar
wafwerar 已提交
351 352 353 354 355 356
#ifdef WINDOWS
  FindClose((*ppDir)->hFind);
  taosMemoryFree(*ppDir);
  *ppDir = NULL;
  return 0;
#else
dengyihao's avatar
dengyihao 已提交
357
  closedir((DIR *)*ppDir);
wafwerar's avatar
wafwerar 已提交
358 359
  *ppDir = NULL;
  return 0;
L
Liu Jicong 已提交
360
#endif
wafwerar's avatar
wafwerar 已提交
361
}