osDir.c 7.6 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 42
#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 已提交
43
    printf("failed to parse relative path:%s to abs path\n", words);
wafwerar's avatar
wafwerar 已提交
44 45 46
    return -1;
  }

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

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

#else
S
Shengliang Guan 已提交
54

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

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

#endif
wafwerar's avatar
wafwerar 已提交
66

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

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

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

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

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

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

94
int32_t taosMkDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
95 96 97 98 99 100 101 102 103
  int32_t code = mkdir(dirname, 0755);
  if (code < 0 && errno == EEXIST) {
    return 0;
  }

  return code;
}

int32_t taosMulMkDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  if (dirname == NULL) return -1;
  char *temp = strdup(dirname);
  char *pos = temp;
  int32_t code = 0;

  if (strncmp(temp, "/", 1) == 0) {
    pos += 1;
  } else if (strncmp(temp, "./", 2) == 0) {
    pos += 2;
  }
  
  for ( ; *pos != '\0'; pos++) {
    if (*pos == '/') {
      *pos = '\0';
      code = mkdir(temp, 0755);
      if (code < 0 && errno != EEXIST) {
        free(temp);
        return code;
      }
      *pos = '/';
    }
  }
  
  if (*(pos - 1) != '/') {
    code = mkdir(temp, 0755);
    if (code < 0 && errno != EEXIST) {
      free(temp);
      return code;
    }
  }
  free(temp);

  // int32_t code = mkdir(dirname, 0755);
S
Shengliang Guan 已提交
137
  if (code < 0 && errno == EEXIST) {
138
    return 0;
S
Shengliang Guan 已提交
139 140
  }

141
  return code;
S
Shengliang Guan 已提交
142 143
}

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

wafwerar's avatar
wafwerar 已提交
148 149
  int64_t sec = taosGetTimestampSec();
  TdDirEntryPtr de = NULL;
S
TD-1263  
Shengliang Guan 已提交
150

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

    char filename[1024];
wafwerar's avatar
wafwerar 已提交
155 156
    snprintf(filename, sizeof(filename), "%s/%s", dirname, taosGetDirEntryName(de));
    if (taosDirEntryIsDir(de)) {
S
TD-1263  
Shengliang Guan 已提交
157 158
      continue;
    } else {
S
Shengliang Guan 已提交
159
      int32_t len = (int32_t)strlen(filename);
S
TD-1574  
Shengliang Guan 已提交
160 161 162 163
      if (len > 3 && strcmp(filename + len - 3, ".gz") == 0) {
        len -= 3;
      }

S
TD-1263  
Shengliang Guan 已提交
164
      int64_t fileSec = 0;
S
Shengliang Guan 已提交
165
      for (int32_t i = len - 1; i >= 0; i--) {
S
TD-1263  
Shengliang Guan 已提交
166
        if (filename[i] == '.') {
S
TD-1263  
Shengliang Guan 已提交
167
          fileSec = atoll(filename + i + 1);
S
TD-1263  
Shengliang Guan 已提交
168 169 170 171
          break;
        }
      }

S
TD-1263  
Shengliang Guan 已提交
172
      if (fileSec <= 100) continue;
dengyihao's avatar
dengyihao 已提交
173
      int32_t days = (int32_t)(TABS(sec - fileSec) / 86400 + 1);
S
TD-1263  
Shengliang Guan 已提交
174
      if (days > keepDays) {
175
        (void)taosRemoveFile(filename);
S
Shengliang Guan 已提交
176
        //printf("file:%s is removed, days:%d keepDays:%d", filename, days, keepDays);
S
TD-1263  
Shengliang Guan 已提交
177
      } else {
S
Shengliang Guan 已提交
178
        //printf("file:%s won't be removed, days:%d keepDays:%d", filename, days, keepDays);
S
TD-1263  
Shengliang Guan 已提交
179 180 181 182
      }
    }
  }

wafwerar's avatar
wafwerar 已提交
183
  taosCloseDir(&pDir);
S
Shengliang Guan 已提交
184
  rmdir(dirname);
S
TD-1263  
Shengliang Guan 已提交
185
}
S
TD-1574  
Shengliang Guan 已提交
186

S
config  
Shengliang Guan 已提交
187
int32_t taosExpandDir(const char *dirname, char *outname, int32_t maxlen) {
S
Shengliang Guan 已提交
188 189
  wordexp_t full_path;
  if (0 != wordexp(dirname, &full_path, 0)) {
S
Shengliang Guan 已提交
190
    //printf("failed to expand path:%s since %s", dirname, strerror(errno));
S
Shengliang Guan 已提交
191
    wordfree(&full_path);
192
    return -1;
S
TD-1574  
Shengliang Guan 已提交
193 194
  }

S
Shengliang Guan 已提交
195 196
  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 已提交
197 198
  }

S
Shengliang Guan 已提交
199
  wordfree(&full_path);
S
TD-1574  
Shengliang Guan 已提交
200

201
  return 0;
S
Shengliang Guan 已提交
202
}
S
TD-1574  
Shengliang Guan 已提交
203

wafwerar's avatar
wafwerar 已提交
204
int32_t taosRealPath(char *dirname, char *realPath, int32_t maxlen) {
S
Shengliang Guan 已提交
205
  char tmp[PATH_MAX] = {0};
wafwerar's avatar
wafwerar 已提交
206
#ifdef WINDOWS
wafwerar's avatar
wafwerar 已提交
207
  if (_fullpath(tmp, dirname, maxlen) != NULL) {
wafwerar's avatar
wafwerar 已提交
208
#else
S
Shengliang Guan 已提交
209
  if (realpath(dirname, tmp) != NULL) {
wafwerar's avatar
wafwerar 已提交
210 211 212 213 214 215 216
#endif
    if (realPath == NULL) {
      strncpy(dirname, tmp, maxlen);
    } else {
      strncpy(realPath, tmp, maxlen);
    }
    return 0;
S
TD-1574  
Shengliang Guan 已提交
217 218
  }

wafwerar's avatar
wafwerar 已提交
219
  return -1;
S
TD-1574  
Shengliang Guan 已提交
220
}
S
Shengliang Guan 已提交
221

222
bool taosIsDir(const char *dirname) {
wafwerar's avatar
wafwerar 已提交
223 224 225
  TdDirPtr pDir = taosOpenDir(dirname);
  if (pDir != NULL) {
    taosCloseDir(&pDir);
226 227 228 229 230
    return true;
  }
  return false;
}

wafwerar's avatar
wafwerar 已提交
231
char* taosDirName(char *name) {
wafwerar's avatar
wafwerar 已提交
232 233 234 235 236 237 238 239 240
#ifdef WINDOWS
  char  Drive1[MAX_PATH], Dir1[MAX_PATH];
  _splitpath(name, Drive1, Dir1, NULL, NULL);
  size_t dirNameLen = strlen(Drive1) + strlen(Dir1);
  if (dirNameLen > 0) {
    name[dirNameLen] = 0;
  }
  return name;
#else
wafwerar's avatar
wafwerar 已提交
241
  return dirname(name);
wafwerar's avatar
wafwerar 已提交
242
#endif
wafwerar's avatar
wafwerar 已提交
243 244 245
}

char* taosDirEntryBaseName(char *name) {
wafwerar's avatar
wafwerar 已提交
246 247 248 249 250 251 252
#ifdef WINDOWS
  char Filename1[MAX_PATH], Ext1[MAX_PATH];
  _splitpath(name, NULL, NULL, Filename1, Ext1);
  return name + (strlen(name) - strlen(Filename1) - strlen(Ext1));
#else
  return (char*)basename(name);
#endif
wafwerar's avatar
wafwerar 已提交
253 254 255 256 257 258
}

TdDirPtr taosOpenDir(const char *dirname) {
  if (dirname == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

#ifdef WINDOWS
  char            szFind[MAX_PATH];  //这是要找的
  HANDLE          hFind;

  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 已提交
276
  return (TdDirPtr)opendir(dirname);
wafwerar's avatar
wafwerar 已提交
277 278
#endif

wafwerar's avatar
wafwerar 已提交
279 280 281 282 283 284
}

TdDirEntryPtr taosReadDir(TdDirPtr pDir) {
  if (pDir == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
285 286 287 288 289 290
#ifdef WINDOWS
  if (!FindNextFile(pDir->hFind, &(pDir->dirEntry.findFileData))) {
    return NULL;
  }
  return (TdDirEntryPtr)&(pDir->dirEntry.findFileData);
#else
wafwerar's avatar
wafwerar 已提交
291
  return (TdDirEntryPtr)readdir((DIR*)pDir);
wafwerar's avatar
wafwerar 已提交
292
#endif
wafwerar's avatar
wafwerar 已提交
293 294 295 296 297 298
}

bool taosDirEntryIsDir(TdDirEntryPtr pDirEntry) {
  if (pDirEntry == NULL) {
    return false;
  }
wafwerar's avatar
wafwerar 已提交
299 300 301
#ifdef WINDOWS
  return (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
wafwerar's avatar
wafwerar 已提交
302
  return (((dirent*)pDirEntry)->d_type & DT_DIR) != 0;
wafwerar's avatar
wafwerar 已提交
303
#endif
wafwerar's avatar
wafwerar 已提交
304 305 306 307 308 309
}

char* taosGetDirEntryName(TdDirEntryPtr pDirEntry) {
  if (pDirEntry == NULL) {
    return NULL;
  }
wafwerar's avatar
wafwerar 已提交
310 311 312
#ifdef WINDOWS
  return pDirEntry->findFileData.cFileName;
#else
wafwerar's avatar
wafwerar 已提交
313
  return ((dirent*)pDirEntry)->d_name;
wafwerar's avatar
wafwerar 已提交
314
#endif
wafwerar's avatar
wafwerar 已提交
315 316
}

wafwerar's avatar
wafwerar 已提交
317 318
int32_t taosCloseDir(TdDirPtr *ppDir) {
  if (ppDir == NULL || *ppDir == NULL) {
wafwerar's avatar
wafwerar 已提交
319 320
    return -1;
  }
wafwerar's avatar
wafwerar 已提交
321 322 323 324 325 326 327 328 329
#ifdef WINDOWS
  FindClose((*ppDir)->hFind);
  taosMemoryFree(*ppDir);
  *ppDir = NULL;
  return 0;
#else
  closedir((DIR*)*ppDir);
  *ppDir = NULL;
  return 0;
L
Liu Jicong 已提交
330
#endif
wafwerar's avatar
wafwerar 已提交
331
}