opendir windows
This code is a port of opendir. readdir and closedir for windows. (include dirent.h on linux)
#include <Windows.h> #include <sys/types.h> #include <stdio.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> #ifdef _WINDOWS_ /* opendir, readdir closedir for windows. include dirent.h on linux */ enum { DT_UNKNOWN = 0, DT_FIFO = 1, DT_CHR = 2, DT_DIR = 4, DT_BLK = 6, DT_REG = 8, DT_LNK = 10, DT_SOCK = 12, DT_WHT = 14 }; struct dirent { ino_t d_ino; /* Inode number */ off_t d_off; /* Not an offset; see below */ unsigned short d_reclen; /* Length of this record */ unsigned char d_type; /* Type of file; not supported by all filesystem types*/ char d_name[256]; /* Null-terminated filename */ }; typedef struct { void *handle; struct dirent dirent; } DIR; DIR *opendir(const char *name); int closedir(DIR *dirp); struct dirent *readdir(DIR *dirp); static int convert_windows_getlasterror_to_posix(int i) { switch (i) { case ERROR_ACCESS_DENIED: return EACCES; case ERROR_ALREADY_EXISTS: return EEXIST; case ERROR_BAD_UNIT: return ENODEV; case ERROR_BUFFER_OVERFLOW: return ENAMETOOLONG; case ERROR_BUSY: return EBUSY; case ERROR_BUSY_DRIVE: return EBUSY; case ERROR_CANNOT_MAKE: return EACCES; case ERROR_CANTOPEN: return EIO; case ERROR_CANTREAD: return EIO; case ERROR_CANTWRITE: return EIO; case ERROR_CURRENT_DIRECTORY: return EACCES; case ERROR_DEV_NOT_EXIST: return ENODEV; case ERROR_DEVICE_IN_USE: return EBUSY; case ERROR_DIR_NOT_EMPTY: return ENOTEMPTY; case ERROR_DIRECTORY: return EINVAL; case ERROR_DISK_FULL: return ENOSPC; case ERROR_FILE_EXISTS: return EEXIST; case ERROR_FILE_NOT_FOUND: return ENOENT; case ERROR_HANDLE_DISK_FULL: return ENOSPC; case ERROR_INVALID_ACCESS: return EACCES; case ERROR_INVALID_DRIVE: return ENODEV; case ERROR_INVALID_FUNCTION: return ENOSYS; case ERROR_INVALID_HANDLE: return EINVAL; case ERROR_INVALID_NAME: return EINVAL; case ERROR_LOCK_VIOLATION: return ENOLCK; case ERROR_LOCKED: return ENOLCK; case ERROR_NEGATIVE_SEEK: return EINVAL; case ERROR_NOACCESS: return EACCES; case ERROR_NOT_ENOUGH_MEMORY: return ENOMEM; case ERROR_NOT_READY: return EAGAIN; case ERROR_NOT_SAME_DEVICE: return EXDEV; case ERROR_OPEN_FAILED: return EIO; case ERROR_OPEN_FILES: return EBUSY; case ERROR_OPERATION_ABORTED: return ECANCELED; case ERROR_OUTOFMEMORY: return ENOMEM; case ERROR_PATH_NOT_FOUND: return ENOENT; case ERROR_READ_FAULT: return EIO; case ERROR_RETRY: return EAGAIN; case ERROR_SEEK: return EIO; case ERROR_SHARING_VIOLATION: return EACCES; case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; case ERROR_WRITE_FAULT: return EIO; case ERROR_WRITE_PROTECT: return EACCES; case WSAEACCES: return EACCES; case WSAEADDRINUSE: return EADDRINUSE; case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL; case WSAEAFNOSUPPORT: return EAFNOSUPPORT; case WSAEALREADY: return EALREADY; case WSAEBADF: return EBADF; case WSAECONNABORTED: return ECONNABORTED; case WSAECONNREFUSED: return ECONNREFUSED; case WSAECONNRESET: return ECONNRESET; case WSAEDESTADDRREQ: return EDESTADDRREQ; case WSAEFAULT: return EFAULT; case WSAEHOSTUNREACH: return EHOSTUNREACH; case WSAEINPROGRESS: return EINPROGRESS; case WSAEINTR: return EINTR; case WSAEINVAL: return EINVAL; case WSAEISCONN: return EISCONN; case WSAEMFILE: return EMFILE; case WSAEMSGSIZE: return EMSGSIZE; case WSAENETDOWN: return ENETDOWN; case WSAENETRESET: return ENETRESET; case WSAENETUNREACH: return ENETUNREACH; case WSAENOBUFS: return ENOBUFS; case WSAENOPROTOOPT: return ENOPROTOOPT; case WSAENOTCONN: return ENOTCONN; case WSAENOTSOCK: return ENOTSOCK; case WSAEOPNOTSUPP: return EOPNOTSUPP; case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT; case WSAEPROTOTYPE: return EPROTOTYPE; case WSAETIMEDOUT: return ETIMEDOUT; case WSAEWOULDBLOCK: return EWOULDBLOCK; } return EPERM; } DIR *opendir(const char *name) { WIN32_FIND_DATAA fdFile; char sPath[MAX_PATH] = {0}; strcat(sPath, name); strcat(sPath, "\\*.*"); HANDLE handle = FindFirstFileA(sPath, &fdFile); if (handle != INVALID_HANDLE_VALUE) { DIR *p = calloc(1, sizeof *p); if (p) { p->handle = handle; return p; } else { /*calloc sets errno to ENOMEM if a memory allocation fails */ FindClose(handle); } } else { errno = convert_windows_getlasterror_to_posix(GetLastError()); } return NULL; } int closedir(DIR *dirp) { FindClose(dirp->handle); free(dirp); return 0; } struct dirent *readdir(DIR *dirp) { WIN32_FIND_DATAA fdFile; BOOL b = FindNextFileA(dirp->handle, &fdFile); if (b) { /*clear*/ memset(&dirp->dirent, 0, sizeof(dirp->dirent)); if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { dirp->dirent.d_type |= DT_DIR; } /*worst case trunks the string*/ strncpy(dirp->dirent.d_name, fdFile.cFileName, sizeof(dirp->dirent.d_name) - 1); return &dirp->dirent; } else { errno = convert_windows_getlasterror_to_posix(GetLastError()); } return NULL; } #endif //_WINDOWS_ int copy_file(const char *pathfrom, const char *pathto) { char buf[4096]; size_t nread; int saved_errno; FILE *fd_from = fopen(pathfrom, "rb"); if (fd_from < 0) return -1; FILE *fd_to = fopen(pathto, "wb"); if (fd_to < 0) goto out_error; while (nread = fread(buf, sizeof(char), sizeof buf, fd_from), nread > 0) { char *out_ptr = buf; size_t nwritten; do { nwritten = fwrite(out_ptr, sizeof(char), nread, fd_to); if (nwritten >= 0) { nread -= nwritten; out_ptr += nwritten; } else { goto out_error; } } while (nread > 0); } if (nread == 0) { if (fclose(fd_to) < 0) { fd_to = NULL; goto out_error; } fclose(fd_from); /* Success! */ return 0; } out_error: saved_errno = errno; fclose(fd_from); if (fd_to != NULL) fclose(fd_to); return saved_errno; } int copy_folder(const char *from, const char *to) { int errcode = _mkdir(to); if (errcode != 0) { return errcode; } DIR *dir = opendir(from); if (dir == NULL) { return errno; } struct dirent *dp; while ((dp = readdir(dir)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { /* skip self and parent */ continue; } char fromlocal[MAX_PATH]; snprintf(fromlocal, MAX_PATH, "%s/%s", from, dp->d_name); char tolocal[MAX_PATH]; snprintf(tolocal, MAX_PATH, "%s/%s", to, dp->d_name); if (dp->d_type & DT_DIR) { errcode = copy_folder(fromlocal, tolocal); } else { errcode = copy_file(fromlocal, tolocal); } if (errcode != 0) break; } closedir(dir); return errcode; } int main(void) { char buffer[200]; _getcwd(buffer, 200); printf("%s\n", buffer); int errcode = copy_folder("from", "to"); return EXIT_SUCCESS; }