This is fileUtils.m in view mode; [Download] [Up]
// ------------------------------------------------------------------------------------- // misc file utilities // ------------------------------------------------------------------------------------- // Permission is granted to freely redistribute this source code, and to use fragments // of this code in your own applications if you find them to be useful. This class, // along with the source code, come with no warranty of any kind, and the user assumes // all responsibility for its use. // ------------------------------------------------------------------------------------- #import <appkit/appkit.h> #import <stdio.h> #import <string.h> #import <ctype.h> #import <libc.h> #import <pwd.h> #import <mntent.h> #import <sys/types.h> #import <sys/stat.h> #import <sys/param.h> #import <sys/dir.h> #import "fileUtils.h" /* return file extension */ const char *XFileExtension(const char *file) { char *temp = rindex(file, '.'); return temp? temp : ""; } /* return file name/extension */ const char *XFileNameExtension(const char *file) { char *temp = rindex(file, '/'); return temp? temp + 1 : file; } /* return true if file exists */ int XFileExists(const char *file) { struct stat st; return file && !stat((char*)file,&st)? 1 : 0; } /* return true if file exists */ int XFileIsDirectory(const char *file) { struct stat st; return file && !stat((char*)file,&st) && (st.st_mode & S_IFDIR)? 1 : 0; } /* return true if file exists */ int XFileIsLink(const char *file) { struct stat st; return file && !lstat((char*)file,&st) && ((st.st_mode & S_IFMT)==S_IFLNK)? 1 : 0; } /* return true if file exists */ char *XFileReadLink(const char *file, char *link) { int len; if (!XFileIsLink(file)) return (char*)NULL; if ((len = readlink(file, link, MAXPATHLEN)) >= 0) link[len] = 0; else *link = 0; return len > 0? link : (char*)NULL; } /* return a file size */ long XFileSize(const char *file) { struct stat st; return file && !stat((char*)file,&st)? st.st_size : -1L; } /* return current dir */ char *XCurrentDir(char *dir) { return (!dir || !getwd(dir))? (char*)NULL : dir; } /* change dir */ int XChangeDir(char *path) { return (!path || (chdir(path) < 0))? -1 : 0; } /* copy a file */ int XCopyFile(const char *fromName, const char *toName, int backup) { int fi = -1, fo = -1, c, stm, mode; char b[10240], bku[MAXPATHLEN + 1]; struct stat st; /* get file mode of toFile */ mode = ((stm = stat(toName, &st)) >= 0)? (st.st_mode & 0777) : 0644; /* file already exist? */ if (backup && (stm >= 0)) { sprintf(bku, "%s~", toName); if (rename(toName, bku)) { NXLogError("copyFile: Unable to rename %s to %s", toName, bku); return -1; } } /* remove to-file */ unlink(toName); /* open/copy/close */ if (((fi = open(fromName, O_RDONLY)) >= 0) && ((fo = open(toName, O_WRONLY | O_CREAT, 0666)) >= 0)) { for (c = 0; !c && ((c = read(fi, b, sizeof(b))) > 0);) c -= write(fo, b, c); } else c = -1; if (fi >= 0) close(fi); if (fo >= 0) close(fo); /* restore backup if error */ if (c && backup && rename(bku, toName)) { NXLogError("copyFile: Unable to restore backup %s after error", bku); return -2; } return c? -3: 0; } /* return server and path to specified file (eg "server:/xyz/file") */ char *XMountPath(char *path, char *mountPath) { FILE *mNum; struct mntent *m; struct stat stpath, stdir; char savName[MAXPATHLEN + 1], savPath[MAXPATHLEN + 1]; int sc; /* init mountPath */ if (mountPath != path) *mountPath = 0; /* make sure file exists */ if (!path || !*path || (stat(path, &stpath) < 0)) return (char*)NULL; /* open mount table */ if (!(mNum = setmntent(MOUNTED, "r"))) return (char*)NULL; /* find remote mount */ *savName = *savPath = 0; for (sc = 0; m = getmntent(mNum); ) { int l; /* validation testing */ if (!strcmp(m->mnt_type, MNTTYPE_IGNORE)) continue; // ignored if (!strcmp(m->mnt_type, MNTTYPE_SWAP )) continue; // ignored if (stat(m->mnt_dir, &stdir) < 0) continue; // can't stat if (stpath.st_dev != stdir.st_dev) continue; // same device if (!(l = strlen(m->mnt_dir))) continue; // empty dir string if (strncmp(m->mnt_dir, path, l)) continue; // not equal /* save dir */ if (!path[l] || (path[l] == '/')) { char *c = m->mnt_dir; int n = 0; for (; *c; c++) { if (*c == '/') n++; } if (!sc || (n > sc)) { sc = n; strcpy(savName, m->mnt_fsname); strcpy(savPath, path + l); } } else if ((l == 1) && (*m->mnt_dir == '/') && !sc) { strcpy(savName, m->mnt_fsname); strcpy(savPath, path); } } /* build mounted path */ if (index(savName, ':')) { sprintf(mountPath, "%s%s", savName, savPath); } else { char *sName = strncmp(savName,"/dev/",5)? savName : savName + 5; char *sPath = *savPath? savPath: "/"; sprintf(mountPath, "#%s:%s", sName, sPath); } return mountPath; } /* resolve all symbolic links in file path */ char *XResolveLinks(char *path, char *nPath) // can do in-place conversion { char wPath[MAXPATHLEN+1], *p, *t; /* init nPath */ if (nPath != path) *nPath = 0; /* return if path not specified */ if (!path || !*path) return (char*)NULL; /* create absolute path to file */ if (*path == '/') strcpy(wPath, path); else if (*path == '~') { struct passwd *pw; char user[128], *p = path + 1; { char *u = user; for (;*p && (*p != '/');) *u++ = *p++; *u = 0; } if (!(pw = *user? getpwnam(user) : getpwuid(getuid()))) return (char*)NULL; sprintf(wPath, "%s%s", pw->pw_dir, p); } else { char curdir[MAXPATHLEN + 1]; if (!getwd(curdir)) return (char*)NULL; sprintf(wPath, "%s/%s", curdir, path); } /* resolve all symbolic links in path */ for (p = wPath, t = nPath; ; *t++ = *p++) { if ((!*p || (*p == '/')) && (t > nPath)) { int l; struct stat st; char sl[MAXPATHLEN + 1], *cp; *t = 0; cp = rindex(nPath, '/'); // should never be null if ((lstat(nPath,&st) >= 0) && ((st.st_mode & S_IFMT) == S_IFLNK) && ((l = readlink(nPath, sl, sizeof(sl)-1)) > 0)) { sl[l] = 0; if (*sl == '/') { // recursion to resolve new link XResolveLinks(sl, nPath); } else { *++cp = 0; strcpy(cp, sl); XResolveLinks(nPath, nPath); } t = nPath + strlen(nPath); } else if (!*(cp + 1)) { // ignore duplicate '/' *(t = cp) = 0; } else if (!strcmp(cp, "/.")) { // ignore self references *(t = cp) = 0; } else if (!strcmp(cp, "/..")) { // back up path *(t = cp) = 0; if (cp = rindex(nPath, '/')) *(t = cp) = 0; } } if (!*p) break; } *t = 0; if (!*nPath) strcpy(nPath, "/"); return nPath; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.