ls.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:16k
源码类别:
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
- // PROGRAM :
- // DATE : Sept. 29 1996
- // AUTHOR : Jarle Aase
- // ---
- // REVISION HISTORY
- //
- #include "stdafx.h"
- #include "WarDaemon.h"
- #include "Unix.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CLs::CLs()
- {
- /* 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 */
- 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;
- }
- CLs::~CLs()
- {
- if (array)
- delete array;
- }
- int CLs::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, "1ACFLRTacdfgikloqrstu")) != EOF) {
- switch (ch) {
- /*
- * The -1, -C and -l options all override each other so shell
- * aliasing works right.
- */
- 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);
- if (argc)
- return ListDir(argc, argv);
- else
- return ListDir(1, dotav);
- return 0;
- }
- int CLs::ListDir(int argc, char **argv)
- {
- BOOL UsePrint = TRUE;
- CString cShowPath, cCurrentPath;
- LPSTR p;
- ASSERT(argc >= 1);
- for(;argc ; argc--, argv++)
- {
- CFileInfoList FileList;
- if (!strcmp(*argv,".\") || !strcmp(*argv,"."))
- {
- cCurrentPath = ".";
- cShowPath = "";
- }
- else
- cCurrentPath = cShowPath = *argv;
- p = cShowPath.GetBuffer(1);
- while (*p)
- {
- if (*p == '\')
- *p = '/';
- ++p;
- }
- cShowPath.ReleaseBuffer();
- ASSERT(AfxIsValidString(*argv));
- BldFileInfoList(FileList, *argv, !f_listdir);
- if (!PrintFileList(FileList, cShowPath))
- return -1;
- if (f_recursive)
- {
- // Grab subdirs too
- CFileInfo *Info;
- LPSTR buf = new char[MAX_PATH];
- *buf = 0;
- int Rval;
- for(Info = NULL; Info = FileList.GetNext(Info); )
- {
- if (IS_DIRECTORY(Info) && strcmp(Info->FileName(),".") && strcmp(Info->FileName(),".."))
- {
- CString cBuf;
- cBuf.Format("%s\%s", cCurrentPath, Info->FileName());
- LPSTR MyArgs[1];
- MyArgs[0] = cBuf.GetBuffer(1);
- if (Rval = ListDir(1, MyArgs))
- return Rval; // Error
- }
- }
- }
- }
- return 0;
- }
- BOOL CLs::PrintFileList(CFileInfoList& 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 */
- CFileInfo *Info;
- 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(Info = NULL, entries = 0; Info = FileList.GetNext(Info);)
- {
- 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 CLs::printscol(CFileInfoList& FileList, LPCSTR Path)
- {
- CFileInfo *Info;
- for(Info = NULL; Info = FileList.GetNext(Info); )
- {
- if (Info->Hide(-1))
- continue;
- printaname(Info, Path);
- putchar('n');
- }
- }
- /*
- * print [inode] [size] name
- * return # of characters printed, no trailing characters.
- */
- int CLs::printaname(CFileInfo *Info, LPCSTR Path)
- {
- int chcnt = 0;
- if (f_inode)
- chcnt += printf("%*lu ", s_inode, Info->GetInode());
- if (f_size)
- chcnt += printf("%*ld ", 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);
- return (chcnt);
- }
- int CLs::printtype(CFileInfo *Info)
- {
- if (IS_DIRECTORY(Info))
- {
- putchar('/');
- return 1;
- }
- //case S_IFIFO:
- // (void)putchar('|');
- // return (1);
- if (IS_LINK(Info))
- {
- putchar('@');
- return 1;
- }
- //case S_IFSOCK:
- // (void)putchar('=');
- // return (1);
- //}
- if (IS_EXEC(Info))
- {
- putchar('*');
- return 1;
- }
- return 0;
- }
- void CLs::printlong(CFileInfoList& FileList, LPCSTR Path)
- {
- char buf[20];
- CFileInfo *Info;
- CString cBuf, cBuf2;
- if (m_Virgin && (f_longform || f_size))
- {
- printf("total %lu%s", btotal, m_CRLF);
- m_Virgin = FALSE;
- }
- for(Info = NULL; Info = FileList.GetNext(Info); )
- {
- if (Info->Hide(-1))
- continue;
- if (f_inode)
- printf("%*lu ", s_inode, Info->GetInode());
- if (f_size)
- printf("%*d ", s_size, (unsigned)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("%*u ", s_size, (unsigned int)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_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 CLs::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 CLs::printcol(CFileInfoList& FileList, LPCSTR Path)
- {
- int base, chcnt, cnt, col, colwidth, num;
- int endcol, numcols, numrows, row;
- CFileInfo *Info;
- /*
- * Have to do random access in the linked list -- build a table
- * of pointers.
- */
- if (entries > lastentries)
- {
- lastentries = entries;
- if (array)
- {
- if ((array = (CFileInfo **)realloc(array, entries * sizeof(CFileInfo *))) == NULL)
- {
- printscol(FileList, Path);
- return;
- }
- }
- else
- {
- if ((array = (CFileInfo **)malloc(entries * sizeof(CFileInfo *))) == NULL)
- {
- printscol(FileList, Path);
- return;
- }
- }
- }
- for(num = 0, Info = NULL; Info = FileList.GetNext(Info); )
- {
- 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 %lu%s", btotal, m_CRLF);
- m_Virgin = FALSE;
- }
- for (row = 0; row < numrows; ++row)
- {
- endcol = colwidth;
- for (base = row, chcnt = col = 0; col < numcols; ++col) {
- chcnt += printaname(array[base]);
- if ((base += numrows) >= num)
- break;
- while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol)
- {
- putchar('t');
- chcnt = cnt;
- }
- endcol += colwidth;
- }
- putchar('n');
- }
- }
- void CLs::usage()
- {
- fprintf(m_stdio, "usage: ls [-1ACFLRTacdfiklqrstu] [file ...]n");
- return;
- }
- int CLs::namecmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- //CFileInfo *Infoa = ((CFileInfo *)(a[0]->m_Ptr));
- //CFileInfo *Infob = ((CFileInfo *)(b[0]->m_Ptr));
- return strcmp(((CFileInfo *)(a[0]->m_Ptr))->FileName(),((CFileInfo *)(b[0]->m_Ptr))->FileName());
- }
- int CLs::revnamecmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return strcmp(((CFileInfo *)(b[0]->m_Ptr))->FileName(),((CFileInfo *)(a[0]->m_Ptr))->FileName());
- }
- int CLs::modcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetModifyTime(),((CFileInfo *)(b[0]->m_Ptr))->GetModifyTime());
- }
- int CLs::revmodcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetModifyTime(),((CFileInfo *)(a[0]->m_Ptr))->GetModifyTime());
- }
- int CLs::acccmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetAccessTime(),((CFileInfo *)(b[0]->m_Ptr))->GetAccessTime());
- }
- int CLs::revacccmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetAccessTime(),((CFileInfo *)(a[0]->m_Ptr))->GetAccessTime());
- }
- int CLs::statcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(a[0]->m_Ptr))->GetLastModeTime(),((CFileInfo *)(b[0]->m_Ptr))->GetLastModeTime());
- }
- int CLs::revstatcmp(const CLinkedListItem **a, const CLinkedListItem **b)
- {
- return CompareFileTime(((CFileInfo *)(b[0]->m_Ptr))->GetLastModeTime(),((CFileInfo *)(a[0]->m_Ptr))->GetLastModeTime());
- }