📄 glob.c
字号:
if (nowtm == NULL)
thisyear = 1970; /* should never happen */
else
thisyear = nowtm->tm_year + 1900;
curdir[0] = '\0';
InitFileInfoList(filp);
for (lp = llp->first; lp != NULL; lp = lp->next) {
len = (int) strlen(STRNCPY(line, lp->line));
if ((line[0] == 't') && (strncmp(line, "total", 5) == 0)) {
/* total XX line? */
if (line[len - 1] != ':') {
hadblankline = 0;
continue;
}
/* else it was a subdir named total */
} else {
for (cp = line; ; cp++) {
if ((*cp == '\0') || (!isspace((int) *cp)))
break;
}
if (*cp == '\0') {
/* Entire line was blank. */
/* separator line between dirs */
hadblankline = 1;
continue;
}
}
if ((hadblankline != 0) && (line[len - 1] == ':')) {
/* newdir */
hadblankline = 0;
if ((line[0] == '.') && (line[1] == '/')) {
line[len - 1] = '/';
(void) memcpy(curdir, line + 2, (size_t) len + 1 - 2);
curdirlen = (size_t) (len - 2);
} else if ((line[0] == '.') && (line[1] == '\\')) {
line[len - 1] = '\\';
(void) memcpy(curdir, line + 2, (size_t) len + 1 - 2);
curdirlen = (size_t) (len - 2);
} else {
line[len - 1] = '/';
(void) memcpy(curdir, line, (size_t) len + 1);
curdirlen = (size_t) len;
}
continue;
}
linesread++;
rc = UnLslRLine(line, curdir, curdirlen, fname, sizeof(fname), linkto, sizeof(linkto), &ftype, &fsize, &ftime, now, thisyear, &plugend);
if ((rc < 0) && (serverType == kServerTypeMicrosoftFTP)) {
rc = UnDosLine(line, curdir, curdirlen, fname, sizeof(fname), &ftype, &fsize, &ftime);
if (rc == 0) {
*linkto = '\0';
plugend = 0;
}
}
if (rc == 0) {
linesconverted++;
fileLen = strlen(fname);
if (fileLen > maxFileLen)
maxFileLen = fileLen;
fi.relnameLen = fileLen;
fi.relname = StrDup(fname);
fi.rname = NULL;
fi.lname = NULL;
fi.rlinkto = (linkto[0] == '\0') ? NULL : StrDup(linkto);
fi.mdtm = ftime;
fi.size = (longest_int) fsize;
fi.type = ftype;
if (plugend > 0) {
fi.plug = (char *) malloc((size_t) plugend + 1);
if (fi.plug != NULL) {
(void) memcpy(fi.plug, line, (size_t) plugend);
fi.plug[plugend] = '\0';
if ((size_t) plugend > maxPlugLen)
maxPlugLen = (size_t) plugend;
}
} else {
fi.plug = (char *) malloc(32);
if (fi.plug != NULL) {
strcpy(fi.plug, "---------- 1 ftpuser ftpusers");
fi.plug[0] = (char) ftype;
if (30 > maxPlugLen)
maxPlugLen = (size_t) 30;
}
}
(void) AddFileInfo(filp, &fi);
}
hadblankline = 0;
}
filp->maxFileLen = maxFileLen;
filp->maxPlugLen = maxPlugLen;
if (linesread == 0)
return (0);
return ((linesconverted > 0) ? linesconverted : (-1));
} /* UnLslR */
int
UnMlsT(const char *const line0, const MLstItemPtr mlip)
{
char *cp, *val, *fact;
int ec;
size_t len;
char line[1024];
memset(mlip, 0, sizeof(MLstItem));
mlip->mode = -1;
mlip->fsize = kSizeUnknown;
mlip->ftype = '-';
mlip->ftime = kModTimeUnknown;
len = strlen(line0);
if (len > (sizeof(line) - 1))
return (-1); /* Line too long, sorry. */
/* This should be re-coded so does not need to make a
* copy of the buffer; it could be done in place.
*/
memcpy(line, line0, len + 1);
/* Skip leading whitespace. */
for (cp = line; *cp != '\0'; cp++) {
if (! isspace(*cp))
break;
}
while (*cp != '\0') {
for (fact = cp; ; cp++) {
if ((*cp == '\0') || (*cp == ' ')) {
/* protocol violation */
return (-1);
}
if (*cp == '=') {
/* End of fact name. */
*cp++ = '\0';
break;
}
}
for (val = cp; ; cp++) {
if (*cp == '\0') {
/* protocol violation */
return (-1);
}
if (*cp == ' ') {
ec = ' ';
*cp++ = '\0';
break;
} else if (*cp == ';') {
if (cp[1] == ' ') {
ec = ' ';
*cp++ = '\0';
*cp++ = '\0';
} else {
ec = ';';
*cp++ = '\0';
}
break;
}
}
if (ISTRNEQ(fact, "OS.", 3))
fact += 3;
if (ISTREQ(fact, "type")) {
if (ISTREQ(val, "file")) {
mlip->ftype = '-';
} else if (ISTREQ(val, "dir")) {
mlip->ftype = 'd';
} else if (ISTREQ(val, "cdir")) {
/* not supported: current directory */
return (-2);
} else if (ISTREQ(val, "pdir")) {
/* not supported: parent directory */
return (-2);
} else {
/* ? */
return (-1);
}
} else if (ISTREQ(fact, "UNIX.mode")) {
if (val[0] == '0')
sscanf(val, "%o", &mlip->mode);
else
sscanf(val, "%i", &mlip->mode);
if (mlip->mode != (-1))
mlip->mode &= 00777;
} else if (ISTREQ(fact, "perm")) {
STRNCPY(mlip->perm, val);
} else if (ISTREQ(fact, "size")) {
#if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG)
(void) sscanf(val, SCANF_LONG_LONG, &mlip->fsize);
#elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ)
mlip->fsize = (longest_int) strtoq(val, NULL, 0);
#else
{
long fsize2 = 0L;
(void) sscanf(val, "%ld", &fsize2);
mlip->fsize = (longest_int) fsize2;
}
#endif
} else if (ISTREQ(fact, "modify")) {
mlip->ftime = UnMDTMDate(val);
} else if (ISTREQ(fact, "UNIX.owner")) {
STRNCPY(mlip->owner, val);
} else if (ISTREQ(fact, "UNIX.group")) {
STRNCPY(mlip->group, val);
} else if (ISTREQ(fact, "UNIX.uid")) {
mlip->uid = atoi(val);
} else if (ISTREQ(fact, "UNIX.gid")) {
mlip->gid = atoi(val);
} else if (ISTREQ(fact, "perm")) {
STRNCPY(mlip->perm, val);
}
/* End of facts? */
if (ec == ' ')
break;
}
len = strlen(cp);
if (len > (sizeof(mlip->fname) - 1)) {
/* Filename too long */
return (-1);
}
memcpy(mlip->fname, cp, len);
/* also set linkto here if used */
return (0);
} /* UnMlsT */
int
UnMlsD(FileInfoListPtr filp, LineListPtr llp)
{
MLstItem mli;
char plug[64];
char og[32];
int rc;
LinePtr lp;
FileInfo fi;
int linesread = 0;
int linesconverted = 0;
int linesignored = 0;
size_t maxFileLen = 0;
size_t maxPlugLen = 0;
size_t fileLen, plugLen;
int m1, m2, m3;
const char *cm1, *cm2, *cm3;
InitFileInfoList(filp);
for (lp = llp->first; lp != NULL; lp = lp->next) {
linesread++;
rc = UnMlsT(lp->line, &mli);
if (rc == 0) {
linesconverted++;
fileLen = strlen(mli.fname);
if (fileLen > maxFileLen)
maxFileLen = fileLen;
fi.relnameLen = fileLen;
fi.relname = StrDup(mli.fname);
fi.rname = NULL;
fi.lname = NULL;
fi.rlinkto = (mli.linkto[0] == '\0') ? NULL : StrDup(mli.linkto);
fi.mdtm = mli.ftime;
fi.size = (longest_int) mli.fsize;
fi.type = mli.ftype;
plug[0] = (char) mli.ftype;
plug[1] = '\0';
m1 = 0;
m2 = 0;
m3 = -1;
if (mli.mode != (-1)) {
m1 = (mli.mode & 00700) >> 6;
m2 = (mli.mode & 00070) >> 3;
m3 = (mli.mode & 00007);
}
if (mli.perm[0] != '\0') {
m3 = 0;
if (fi.type == 'd') {
if (strchr(mli.perm, 'e') != NULL) {
/* execute -> execute */
m3 |= 00001;
}
if (strchr(mli.perm, 'c') != NULL) {
/* create -> write */
m3 |= 00002;
}
if (strchr(mli.perm, 'l') != NULL) {
/* list -> read */
m3 |= 00004;
}
} else {
if (strchr(mli.perm, 'w') != NULL) {
/* write -> write */
m3 |= 00002;
}
if (strchr(mli.perm, 'r') != NULL) {
/* read -> read */
m3 |= 00004;
}
}
}
if (m3 != (-1)) {
cm1 = rwx[m1];
cm2 = rwx[m2];
cm3 = rwx[m3];
sprintf(plug + 1, "%s%s%s", cm1, cm2, cm3);
}
if (mli.owner[0] != '\0') {
if (mli.group[0] != '\0') {
#ifdef HAVE_SNPRINTF
snprintf(og, sizeof(og) - 1,
#else
sprintf(og,
#endif /* HAVE_SNPRINTF */
" %-8.8s %s",
mli.owner, mli.group
);
STRNCAT(plug, og);
} else {
STRNCAT(plug, " ");
STRNCAT(plug, mli.owner);
}
}
fi.plug = StrDup(plug);
if (fi.plug != NULL) {
plugLen = strlen(plug);
if (plugLen > maxPlugLen)
maxPlugLen = plugLen;
}
(void) AddFileInfo(filp, &fi);
} else if (rc == (-2)) {
linesignored++;
}
}
filp->maxFileLen = maxFileLen;
filp->maxPlugLen = maxPlugLen;
if (linesread == 0)
return (0);
linesconverted += linesignored;
return ((linesconverted > 0) ? linesconverted : (-1));
} /* UnMlsD */
#if 0
static void
print1(FileInfoListPtr list)
{
FileInfoPtr fip;
int i;
for (i = 1, fip = list->first; fip != NULL; fip = fip->next, i++)
printf("%d: %s\n", i, fip->relname == NULL ? "NULL" : fip->relname);
}
static void
print2(FileInfoListPtr list)
{
FileInfoPtr fip;
int i, n;
n = list->nFileInfos;
for (i=0; i<n; i++) {
fip = list->vec[i];
printf("%d: %s\n", i + 1, fip->relname == NULL ? "NULL" : fip->relname);
}
}
static void
SortRecursiveFileList(FileInfoListPtr files)
{
VectorizeFileInfoList(files);
SortFileInfoList(files, 'b', '?');
UnvectorizeFileInfoList(files);
} /* SortRecursiveFileList */
#endif
int
FTPRemoteRecursiveFileList1(FTPCIPtr cip, char *const rdir, FileInfoListPtr files)
{
LineList dirContents;
FileInfoList fil;
char cwd[512];
int result;
if ((result = FTPGetCWD(cip, cwd, sizeof(cwd))) < 0)
return (result);
InitFileInfoList(files);
if (rdir == NULL)
return (-1);
if (FTPChdir(cip, rdir) < 0) {
/* Probably not a directory.
* Just add it as a plain file
* to the list.
*/
(void) ConcatFileToFileInfoList(files, rdir);
return (kNoErr);
}
/* Paths collected must be relative. */
if ((result = FTPListToMemory2(cip, "", &dirContents, "-lRa", 1, (int *) 0)) < 0) {
if ((result = FTPChdir(cip, cwd)) < 0) {
return (result);
}
}
(void) UnLslR(&fil, &dirContents, cip->serverType);
DisposeLineListContents(&dirContents);
/* Could sort it to breadth-first here. */
/* (void) SortRecursiveFileList(&fil); */
(void) ComputeRNames(&fil, rdir, 1, 1);
(void) ConcatFileInfoList(files, &fil);
DisposeFileInfoListContents(&fil);
if ((result = FTPChdir(cip, cwd)) < 0) {
return (result);
}
return (kNoErr);
} /* FTPRemoteRecursiveFileList1 */
int
FTPRemoteRecursiveFileList(FTPCIPtr cip, LineListPtr fileList, FileInfoListPtr files)
{
LinePtr filePtr, nextFilePtr;
LineList dirContents;
FileInfoList fil;
char cwd[512];
int result;
char *rdir;
if ((result = FTPGetCWD(cip, cwd, sizeof(cwd))) < 0)
return (result);
InitFileInfoList(files);
for (filePtr = fileList->first;
filePtr != NULL;
filePtr = nextFilePtr)
{
nextFilePtr = filePtr->next;
rdir = filePtr->line;
if (rdir == NULL)
continue;
if (FTPChdir(cip, rdir) < 0) {
/* Probably not a directory.
* Just add it as a plain file
* to the list.
*/
(void) ConcatFileToFileInfoList(files, rdir);
continue;
}
/* Paths collected must be relative. */
if ((result = FTPListToMemory2(cip, "", &dirContents, "-lRa", 1, (int *) 0)) < 0) {
goto goback;
}
(void) UnLslR(&fil, &dirContents, cip->serverType);
DisposeLineListContents(&dirContents);
(void) ComputeRNames(&fil, rdir, 1, 1);
(void) ConcatFileInfoList(files, &fil);
DisposeFileInfoListContents(&fil);
goback:
if ((result = FTPChdir(cip, cwd)) < 0) {
return (result);
}
}
return (kNoErr);
} /* FTPRemoteRecursiveFileList */
#if defined(WIN32) || defined(_WINDOWS)
static void
Traverse(FTPCIPtr cip, char *fullpath, struct Stat *st, char *relpath, FileInfoListPtr filp)
{
WIN32_FIND_DATA ffd;
HANDLE searchHandle;
DWORD dwErr;
char *cp, *c2;
const char *file;
FileInfo fi;
/* Handle directory entry first. */
if (relpath[0] != '\0') {
fi.relname = StrDup(relpath);
fi.rname = NULL;
fi.lname = StrDup(fullpath);
fi.rlinkto = NULL;
fi.plug = NULL;
fi.mdtm = st->st_mtime;
fi.size = (longest_int) st->st_size;
fi.type = 'd';
(void) AddFileInfo(filp, &fi);
}
cp = fullpath + strlen(fullpath);
*cp++ = LOCAL_PATH_DELIM;
strcpy(cp, "*.*");
c2 = relpath + strlen(relpath);
*c2++ = LOCAL_PATH_DELIM;
*c2 = '\0';
memset(&ffd, 0, sizeof(ffd));
/* "Open" the directory. */
searchHandle = FindFirstFile(fullpath, &ffd);
if (searchHandle == INVALID_HANDLE_VALUE) {
return;
}
for (;;) {
file = ffd.cFileName;
if ((*file == '.') && ((file[1] == '\0') || ((file[1] == '.') && (file[2] == '\0')))) {
/* It was "." or "..", so skip it. */
goto next;
}
(void) strcpy(cp, file); /* append name after slash */
(void) strcpy(c2, file);
if (Lstat(fullpath, st) < 0) {
Error(cip, kDoPerror, "could not stat %s.\n", fullpath);
goto next;
}
fi.relname = StrDup(relpath + (((relpath[0] == '/') || (relpath[0] == '\\')) ? 1 : 0));
fi.rname = NULL;
fi.lname = StrDup(fullpath);
fi.mdtm = st->st_mtime;
fi.size = (longest_int) st->st_size;
fi.rlinkto = NULL;
fi.plug = NULL;
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
Traverse(cip, fullpath, st, relpath, filp);
} else {
/* file */
fi.type = '-';
(void) AddFileInfo(filp, &fi);
}
next:
#if _DEBUG
memset(&ffd, 0, sizeof(ffd));
#endif
if (!FindNextFile(searchHandle, &ffd)) {
dwErr = GetLastError();
if (dwErr != ERROR_NO_MORE_FILES) {
FindClose(searchHandle);
return;
}
break;
}
}
FindClose(searchHandle);
} // Traverse
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -