/** * @file disk_deep_mkdir.c * @brief 途中のディレクトリも掘る mkdir. * @author tenk* * @note * - win/linux(unix)用. * - Public Domain Software */ #include "disk_deep_mkdir.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #ifdef _WIN32 #include <tchar.h> #include <io.h> #include <tchar.h> #else // win以外ではcharのみ. #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #ifndef TCHAR #define _T(x) x #define TCHAR char #endif #endif #ifndef FNAME_INCLUDED // fname.h を読み込んでなかったら交替物を用意. #ifdef _WIN32 #define FNAME_MAX_PATH _MAX_PATH #define FNAME_LEN(s) _tcslen(s) #define FNAME_SEP_CHR _T('\\') #define fname_cpy(d,l,s) ((d)[(l)-1]=0, _tcsncpy((d),(s),(l)-1)) TCHAR* fname_baseName(const TCHAR* p) { const TCHAR *adr = p; while (*p) { if (*p == _T(':') || *p == _T('/') || *p == _T('\\')) adr = p + 1; p = CharNext((TCHAR*)p); } return (TCHAR*)adr; } #else #define FNAME_MAX_PATH 4096 #define FNAME_LEN(s) strlen(s) #define FNAME_SEP_CHR '/' #define fname_cpy(d,l,s) ((d)[(l)-1]=0, strncpy((d),(s),(l)-1)) char* fname_baseName(const char* p) { const char *adr = p; while (*p) { char c = *p++; if (c == ':' || c == '/') adr = p; } return (char*)adr; } #endif #endif #ifndef DISK_H #ifdef _WIN32 static __inline int disk_mkdir(const TCHAR* fname) { return CreateDirectory(fname,NULL) ? 0 : -1; } #else static inline int disk_mkdir(const char* fname) { return mkdir(fname, 0777); } #endif #endif /** 途中のディレクトリも掘る mkdir. */ int disk_deep_mkdir(const TCHAR *name) { TCHAR nm[ FNAME_MAX_PATH + 1 ]; TCHAR* e; TCHAR* s; #ifdef _WIN32 unsigned atr = GetFileAttributes(name); if (atr != 0xFFFFFFFF) { if (atr & FILE_ATTRIBUTE_DIRECTORY) return 0; return -1; // ディレクトリでないファイルだったのでアウト. } #else { struct stat s; stat(name, &s); if (s.st_mode & S_IFDIR) return 0; } #endif if (disk_mkdir(name) == 0) return 0; fname_cpy(nm, FNAME_MAX_PATH, name); e = nm + FNAME_LEN(nm); for (;;) { s = fname_baseName(nm); if (s <= nm) return -1; // 失敗. --s; *s = 0; if (disk_mkdir(nm) == 0) { do { *s = FNAME_SEP_CHR; s += FNAME_LEN(s); if (s >= e) return disk_mkdir(nm); } while (disk_mkdir(nm) == 0); return -1; } } }