ls.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:17k
源码类别:
Ftp客户端
开发平台:
Visual C++
- // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
- // Copyright 1996 by Jarle Aase. All rights reserved.
- // See the "War Software Series Licende Agreement" for details concerning
- // use and distribution.
- // ---
- // This source code, executables and programs containing source code or
- // binaries or proprietetary technology from the War Software Series are
- // NOT alloed used, viewed or tested by any governmental agencies in
- // any countries. This includes the government, departments, police,
- // military etc.
- // ---
- // This file is intended for use with Tab space = 2
- // Created and maintained in MSVC Developer Studio
- // ---
- // NAME : ls.cpp
- // PURPOSE : UNIX ls command for VfSys.dll
- // PROGRAM :
- // DATE : Mar 29 1997
- // AUTHOR : Jarle Aase
- // ---
- //
- // The best design would be to use the CLs class, and let that call VfSys at
- // need, but it is faster to do the job in one go from the VfSys worker thread.
- //
- // REVISION HISTORY
- //
- #include "stdafx.h"
- // For now, we don't support non-daemon programs
- //#include "WarSoftware.h"
- #include "WarDaemon.h"
- #include "WarFsys.h"
- #include "VfFSys.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CVfSysLs::CVfSysLs()
- {
- /* Terminal defaults to -Cq, non-terminal defaults to -1. */
- termwidth = 80;
- blocksize = 0;
- f_followLinks = 0;
- output = 0;
- btotal = 0;
- maxsize = 0;
- s_block = s_group = s_inode = s_nlink = s_size = s_user = 0;
- f_accesstime = 0; /* use time of last access */
- f_column = 0; /* columnated format */
- f_flags = 0; /* show flags associated with a file */
- f_inode = 0; /* print inode */
- f_kblocks = 0; /* print size in kilobytes */
- f_listdir = 0; /* list actual directory, not contents */
- f_listdot = 0; /* list files beginning with . */
- f_hidethisandprevdotdir = 1;
- f_longform = 0; /* long listing format */
- f_newline = 0; /* if precede with newline */
- f_nonprint = 0; /* show unprintables as ? */
- f_nosort = 0; /* don't sort output */
- f_recursive = 0; /* ls subdirectories also */
- f_reversesort = 0; /* reverse whatever sort is used */
- f_sectime = 0; /* print the real time for all files */
- f_singlecol = 1 ; /* use single column output */
- f_size = 0; /* list size in short listing */
- f_statustime = 0 ; /* use time of last mode change */
- f_dirname = 0; /* if precede with directory name */
- f_timesort = 0; /* sort by time vice name */
- f_type = 0; /* add type character for non-regular files */
- f_comment = 0; // Print comments
- f_printdlc = 0; // Print download count
- m_CRLF = "rn"; // On binary transferes we will need "n" only..
- // Used by getopt()
- opterr = 0; /* if error message should be printed */
- optind = 0; /* index into parent argv vector */
- optopt = 0; /* character checked for validity */
- optarg = NULL; /* argument associated with option */
- m_Virgin = TRUE;
- array = NULL;
- lastentries = -1;
- }
- CVfSysLs::~CVfSysLs()
- {
- if (array)
- free(array);
- }
- int CVfSysLs::main(int argc, char **argv)
- {
- static char dot[] = "./", *dotav[] = { dot, NULL };
- //struct winsize win;
- int ch;
- /* Root is -A automatically. */
- if (!getuid())
- f_listdot = 1;
- while ((ch = getopt(argc, argv, "ID1ACFLRTacdfgikloqrstu")) != EOF) {
- switch (ch) {
- /*
- * The -1, -C and -l options all override each other so shell
- * aliasing works right.
- */
- // War Extentions: -D Print dl count + comment, -I Ptint comment
- case 'D':
- f_printdlc = 1;
- // fall trough
- case 'I':
- f_comment = 1;
- break;
- // Standatd UNIX ls flags
- case '1':
- f_singlecol = 1;
- f_column = f_longform = 0;
- break;
- case 'C':
- f_column = 1;
- f_longform = f_singlecol = 0;
- break;
- case 'l':
- f_longform = 1;
- f_column = f_singlecol = 0;
- break;
- /* The -c and -u options override each other. */
- case 'c':
- f_statustime = 1;
- f_accesstime = 0;
- break;
- case 'u':
- f_accesstime = 1;
- f_statustime = 0;
- break;
- case 'F':
- f_type = 1;
- break;
- case 'L':
- m_ShowLinkAsFile = TRUE;
- break;
- case 'R':
- f_recursive = 1;
- break;
- case 'a':
- //fts_options |= FTS_SEEDOT;
- f_hidethisandprevdotdir = 0;
- /* FALLTHROUGH */
- case 'A':
- f_listdot = 1;
- break;
- /* The -d option turns off the -R option. */
- case 'd':
- f_listdir = 1;
- f_recursive = 0;
- break;
- case 'f':
- f_nosort = 1;
- break;
- case 'g': /* Compatibility with 4.3BSD. */
- break;
- case 'i':
- f_inode = 1;
- break;
- case 'k':
- f_kblocks = 1;
- break;
- case 'o':
- f_flags = 1;
- break;
- case 'q':
- f_nonprint = 1;
- break;
- case 'r':
- f_reversesort = 1;
- break;
- case 's':
- f_size = 1;
- break;
- case 'T':
- f_sectime = 1;
- break;
- case 't':
- f_timesort = 1;
- break;
- default:
- case 'h':
- usage();
- return 0;
- }
- }
- argc -= optind;
- argv += optind;
- /*
- * If not -F, -i, -l, -s or -t options, don't require stat
- * information.
- */
- /*
- * If not -F, -d or -l options, follow any symbolic links listed on
- * the command line.
- */
- if (!f_longform && !f_listdir && !f_type)
- f_followLinks = 1;
- if (f_singlecol && !f_recursive)
- f_dirname = 1;
- /* Select a sort function. */
- if (f_reversesort) {
- if (!f_timesort)
- sortfcn = revnamecmp;
- else if (f_accesstime)
- sortfcn = revacccmp;
- else if (f_statustime)
- sortfcn = revstatcmp;
- else /* Use modification time. */
- sortfcn = revmodcmp;
- } else {
- if (!f_timesort)
- sortfcn = namecmp;
- else if (f_accesstime)
- sortfcn = acccmp;
- else if (f_statustime)
- sortfcn = statcmp;
- else /* Use modification time. */
- sortfcn = modcmp;
- }
- ASSERT(argc >= 0);
- int Rval = 0;
- if (argc)
- Rval = ListDir(argc, argv);
- else
- Rval = ListDir(1, dotav);
- return Rval;
- }
- int CVfSysLs::ListDir(int argc, char **argv)
- {
- int argcSave = argc;
- char **argvSave = argv;
- for(;argc ; argc--, argv++)
- {
- // Prepere file system
- CString Path = *argv;
- m_pFsysThread->ParsePath(Path);
- m_pFsysThread->ScanPath(Path, FALSE, f_recursive, FALSE);
- }
- pLock->ReadLock();
- int Rval = _ListDir(argcSave, argvSave);
- pLock->UnlockRead();
- return Rval;
- }
- int CVfSysLs::_ListDir(int argc, char **argv)
- {
- BOOL UsePrint = TRUE;
- CString cShowPath, cCurrentPath;
- ASSERT(argc >= 1);
- for(;argc ; argc--, argv++)
- {
- CFileList FileList;
- CLinkedListItem *Item;
- ASSERT(AfxIsValidString(*argv));
- if (m_VisitedDirs.Find(*argv))
- continue; // Already been here
- cCurrentPath = cShowPath = *argv;
- m_pFsysThread->BldFileInfoList(FileList, *argv, !f_listdir);
- if (!PrintFileList(FileList, cShowPath))
- return -1;
- if (f_recursive)
- {
- // Grab subdirs too
- int Rval;
- m_VisitedDirs.AddHead(*argv);
- for(Item = FileList.First(); Item; Item = FileList.Next(Item))
- {
- FILE_NODE *pNode = (FILE_NODE *)FileList.Ptr(Item);
- if ((pNode->Perms & NODE_DIR)
- && strcmp(pNode->Name,".") && strcmp(pNode->Name,".."))
- {
- CString cBuf;
- cBuf.Format("%s/%s", cCurrentPath, pNode->Name);
- LPSTR MyArgs[1];
- MyArgs[0] = cBuf.GetBuffer(1);
- if (Rval = ListDir(1, MyArgs))
- return Rval; // Error
- }
- }
- }
- }
- return 0;
- }
- BOOL CVfSysLs::PrintFileList(CFileList& FileList, LPCSTR Path)
- {
- FLEN maxblock, maxinode, maxnlink;
- int bcfile, flen, glen, ulen, maxflags, maxgroup, maxuser;
- int needstats;
- LPCSTR user, group ,flags;
- char buf[20]; /* 32 bits == 10 digits */
- CPseudoFileInfo Info;
- CLinkedListItem *Item;
- LPCSTR FileName;
- CString cBuf;
- if (!f_nosort)
- FileList.Sort((int (*)(const void *, const void *))sortfcn);
- needstats = f_inode || f_longform || f_size;
- flen = 0;
- maxblock = maxinode = maxnlink = (FLEN)0;
- btotal = maxlen = 0;
- bcfile = 0;
- maxuser = maxgroup = maxflags = 0;
- flags = NULL;
- maxsize = 0;
- for(Item = FileList.First(), entries = 0; Item; Item = FileList.Next(Item))
- {
- Info = (FILE_NODE *)FileList.Ptr(Item);
- FileName = Info.FileName();
- ASSERT(AfxIsValidString(FileName));
- if (ISDOT(FileName) && !f_listdot)
- {
- //Info.Hide(TRUE);
- continue;
- }
- else if (f_hidethisandprevdotdir && (!strcmp(FileName,".") || !strcmp(FileName,"..")))
- {
- //Info.Hide(TRUE);
- continue;
- }
- if (f_nonprint)
- {
- Info.MakeFileNameASCII();
- }
- if (Info.GetFileNameLen() > maxlen)
- maxlen = Info.GetFileNameLen() ;
- if (needstats)
- {
- FLEN NumBlocks = Info.GetFileBlocks();
- if (NumBlocks > maxblock)
- maxblock = NumBlocks;
- if ((FLEN)Info.GetInode() > maxinode)
- (FLEN)maxinode = Info.GetInode();
- if ((FLEN)Info.GetLinks() > maxnlink)
- maxnlink = (FLEN)Info.GetLinks();
- if (Info.GetFileLength() > maxsize)
- maxsize = Info.GetFileLength();
- btotal += NumBlocks;
- btotal++;
- if (f_longform)
- {
- user = Info.GetUserName(cBuf);
- if ((ulen = strlen(user)) > maxuser)
- maxuser = ulen;
- group = Info.GetGroupName(cBuf);
- if ((glen = strlen(group)) > maxgroup)
- maxgroup = glen;
- /*if (f_flags) {
- flags = flags_to_string(sp->st_flags, "-");
- if ((flen = strlen(flags)) > maxflags)
- maxflags = flen;
- } else */
- flen = 0;
- /*if (S_ISCHR(sp->st_mode) ||
- S_ISBLK(sp->st_mode))
- bcfile = 1;*/
- /*if (f_flags) {
- np->flags = &np->data[ulen + glen + 2];
- (void)strcpy(np->flags, flags);
- }*/
- }
- }
- ++entries;
- }
- if (!entries)
- return TRUE;
- if (needstats)
- {
- _snprintf(buf, sizeof(buf), "%lu", maxblock);
- s_block = strlen(buf);
- _snprintf(buf, sizeof(buf), "%lu", maxinode);
- s_inode = strlen(buf);
- _snprintf(buf, sizeof(buf), "%lu", maxnlink);
- s_nlink = strlen(buf);
- _snprintf(buf, sizeof(buf), "%lu", maxsize);
- s_size = strlen(buf);
- s_user = maxuser;
- }
- /*
- * If already output something, put out a newline as
- * a separator. If multiple arguments, precede each
- * directory with its name.
- */
- if (output)
- printf("n%s:n", Path);
- /* Select a print function. */
- if (f_singlecol)
- printscol(FileList, Path);
- else if (f_longform)
- printlong(FileList, Path);
- else
- printcol(FileList, Path);
- output = 1;
- return TRUE;
- }
- void CVfSysLs::printscol(CFileList& FileList, LPCSTR Path)
- {
- CPseudoFileInfo Info;
- CLinkedListItem *Item;
- for(Item = FileList.First(), entries = 0; Item; Item = FileList.Next(Item))
- {
- Info = (FILE_NODE *)FileList.Ptr(Item);
- if (Info.Hide(-1))
- continue;
- printaname(Info, Path);
- putchar('n');
- }
- }
- /*
- * print [inode] [size] name
- * return # of characters printed, no trailing characters.
- */
- int CVfSysLs::printaname(CPseudoFileInfo& Info, LPCSTR Path)
- {
- int chcnt = 0;
- if (f_inode)
- chcnt += printf("%*lu ", s_inode, Info.GetInode());
- if (f_size)
- chcnt += printf("%*I64d ", s_size, Info.GetFileLength());
- if (f_dirname && Path && *Path)
- {
- int ofs = 0;
- if ((Path[0] == '.') && (Path[1] == '/'))
- ofs = 2;
- if (Path[ofs])
- chcnt += printf("%s/", Path + ofs);
- }
- chcnt += printf("%s", Info.FileName());
- if (f_type)
- chcnt += printtype(Info);
- if (f_comment)
- chcnt += printcomment(Info);
- return (chcnt);
- }
- int CVfSysLs::printcomment(CPseudoFileInfo& Info)
- {
- int chcnt = 0;
- if (f_printdlc)
- chcnt += printf(" %u", Info.GetDLC());
- chcnt += printf(" %s", Info.GetComment());
- return chcnt;
- }
- int CVfSysLs::printtype(CPseudoFileInfo& Info)
- {
- if (Info.IsDirectory())
- {
- putchar('/');
- return 1;
- }
- //case S_IFIFO:
- // (void)putchar('|');
- // return (1);
- if (Info.IsLink())
- {
- putchar('@');
- return 1;
- }
- //case S_IFSOCK:
- // (void)putchar('=');
- // return (1);
- //}
- /*
- if (IS_EXEC(Info))
- {
- putchar('*');
- return 1;
- }
- */
- return 0;
- }
- void CVfSysLs::printlong(CFileList& FileList, LPCSTR Path)
- {
- char buf[20];
- CPseudoFileInfo Info;
- CLinkedListItem *Item;
- CString cBuf, cBuf2;
- if (m_Virgin && (f_longform || f_size))
- {
- printf("total %I64d%s", btotal, m_CRLF);
- m_Virgin = FALSE;
- }
- for(Item = FileList.First(); Item; Item = FileList.Next(Item))
- {
- Info = (FILE_NODE *)FileList.Ptr(Item);
- if (Info.Hide(-1))
- continue;
- if (f_inode)
- printf("%*lu ", s_inode, Info.GetInode());
- if (f_size)
- printf("%*I64d ", s_size, Info.GetFileBlocks());
- strmode(Info, buf);
- printf("%s %*u %-*s %-*s ", buf, s_nlink,
- Info.GetLinks(), s_user, Info.GetUserName(cBuf), s_group,
- Info.GetGroupName(cBuf2));
- printf("%*I64d ", s_size, Info.GetFileLength());
- if (f_accesstime)
- printtime(Info.GetAccessTime());
- else if (f_statustime)
- printtime(Info.GetLastModeTime());
- else
- printtime(Info.GetModifyTime());
- printf("%s", Info.FileName());
- if (f_comment)
- printcomment(Info);
- if (f_type)
- printtype(Info);
- //if (S_ISLNK(sp->st_mode))
- // printlink(p);
- putchar('n');
- }
- }
- static const char *Months[] = {{"Jan"}, {"Feb"}, {"Mar"}, {"Apr"}, {"May"}, {"Jun"},
- {"Jul"}, {"Aug"}, {"Sep"}, {"Oct"}, {"Nov"}, {"Dec"}};
- void CVfSysLs::printtime(LPFILETIME ftime)
- {
- ASSERT(AfxIsValidAddress(ftime,sizeof(FILETIME)));
- FILETIME lt;
- SYSTEMTIME st, tn;
- FileTimeToLocalFileTime(ftime,<);
- FileTimeToSystemTime(<,&st);
- GetSystemTime(&tn);
- if ((st.wMonth <= 0) || (st.wMonth > 12))
- st.wMonth = 1;
- if ((st.wDay < 0) || (st.wDay >= 32))
- st.wDay = 1;
- printf("%s %2d ", SafeStringIndex(Months,st.wMonth -1, 12), st.wDay);
- if (st.wYear && (tn.wYear == st.wYear))
- printf("%02d:%02d ", st.wHour, st.wMinute);
- else
- printf(" %04d ", (st.wYear > 1970) ? st.wYear : 1990);
- }
- #ifdef TAB
- #undef TAB
- #endif
- #define TAB 8
- void CVfSysLs::printcol(CFileList& FileList, LPCSTR Path)
- {
- int base, chcnt, cnt, col, colwidth, num;
- int endcol, numcols, numrows, row;
- CPseudoFileInfo Info;
- CLinkedListItem *Item;
- /*
- * Have to do random access in the linked list -- build a table
- * of pointers.
- */
- if (entries > lastentries)
- {
- lastentries = entries;
- if (array)
- {
- if ((array = (FILE_NODE **)realloc(array, entries * sizeof(CFileInfo *))) == NULL)
- {
- printscol(FileList, Path);
- return;
- }
- }
- else
- {
- if ((array = (FILE_NODE **)malloc(entries * sizeof(CFileInfo *))) == NULL)
- {
- printscol(FileList, Path);
- return;
- }
- }
- }
- for(Item = FileList.First(), num = 0; Item; Item = FileList.Next(Item))
- {
- Info = (FILE_NODE *)FileList.Ptr(Item);
- if (!Info.Hide(-1))
- array[num++] = Info;
- }
- colwidth = maxlen;
- if (f_inode)
- colwidth += s_inode + 1;
- if (f_size)
- colwidth += s_block + 1;
- if (f_type)
- colwidth += 1;
- colwidth = (colwidth + TAB) & ~(TAB - 1);
- if (termwidth < 2 * colwidth)
- {
- printscol(FileList, Path);
- return;
- }
- numcols = termwidth / colwidth;
- numrows = num / numcols;
- if (num % numcols)
- ++numrows;
- if (m_Virgin && (f_longform || f_size))
- {
- printf("total %I64d%s", btotal, m_CRLF);
- m_Virgin = FALSE;
- }
- for (row = 0; row < numrows; ++row)
- {
- endcol = colwidth;
- for (base = row, chcnt = col = 0; col < numcols; ++col)
- {
- Info = array[base];
- chcnt += printaname(Info, Path);
- if ((base += numrows) >= num)
- break;
- while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol)
- {
- putchar('t');
- chcnt = cnt;
- }
- endcol += colwidth;
- }
- putchar('n');
- }
- }
- void CVfSysLs::usage()
- {
- fprintf(m_stdio, "usage: ls [-1ACFLRTacdfiklqrstu] [file ...]n");
- return;
- }
- int CVfSysLs::namecmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- //CFileInfo *Infoa = ((CFileInfo *)(a[0]->m_Ptr));
- //CFileInfo *Infob = ((CFileInfo *)(b[0]->m_Ptr));
- return strcmp(((LPCFILE_NODE)(a[0]->m_Ptr))->Name,((LPCFILE_NODE )(b[0]->m_Ptr))->Name);
- }
- int CVfSysLs::revnamecmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return strcmp(((LPCFILE_NODE )(b[0]->m_Ptr))->Name,((LPCFILE_NODE)(a[0]->m_Ptr))->Name);
- }
- int CVfSysLs::modcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetModifyTime(),((CFileInfo *)(b[0]->m_Ptr))->GetModifyTime());
- }
- int CVfSysLs::revmodcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetModifyTime(),((CFileInfo *)(a[0]->m_Ptr))->GetModifyTime());
- }
- int CVfSysLs::acccmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetAccessTime(),((CFileInfo *)(b[0]->m_Ptr))->GetAccessTime());
- }
- int CVfSysLs::revacccmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetAccessTime(),((CFileInfo *)(a[0]->m_Ptr))->GetAccessTime());
- }
- int CVfSysLs::statcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetLastModeTime(),((CFileInfo *)(b[0]->m_Ptr))->GetLastModeTime());
- }
- int CVfSysLs::revstatcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetLastModeTime(),((CFileInfo *)(a[0]->m_Ptr))->GetLastModeTime());
- }