⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ls.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <config.h>#include "ftpd.h"#include "ls_p.h"#include "bsd-glob.h"#include "messages.h"#include "dynamic.h"#include "ftpwho-update.h"#include "globals.h"#ifdef WITH_DMALLOC# include <dmalloc.h>#endifstatic void wrstr(const int f, const char *s){    static char outbuf[CONF_TCP_SO_SNDBUF];    static size_t outcnt;    size_t l;        if (s == NULL) {        if (outcnt > (size_t) 0U) {            if (safe_write(f, outbuf, outcnt) != 0) {                return;            }        }        outcnt = (size_t) 0U;        return;    }    if ((l = strlen(s)) <= (size_t) 0U) {        return;    }    if (l <= (sizeof outbuf - outcnt)) {        memcpy(outbuf + outcnt, s, l); /* secure, see above */        outcnt += l;        return;    }    if (outcnt < sizeof outbuf) {        const size_t rest = sizeof outbuf - outcnt;                memcpy(outbuf + outcnt, s, rest);   /* secure, see above */        s += rest;        l -= rest;    }    if (safe_write(f, outbuf, sizeof outbuf) != 0) {        return;    }    while (l > sizeof outbuf) {        if (safe_write(f, s, sizeof outbuf) != 0) {            return;        }        s += sizeof outbuf;        l -= sizeof outbuf;    }    if (l > (size_t) 0U) {        memcpy(outbuf, s, l);          /* safe, l <= sizeof outbuf */        outcnt = l;    }}#ifdef NO_FTP_USERSconst char *getname(const uid_t uid){    static char number[9];    if (SNCHECK(snprintf(number, sizeof number, "%-8d", uid), sizeof number)) {        _EXIT(EXIT_FAILURE);    }    return number;}const char *getgroup(const gid_t gid){    static char number[9];    if (SNCHECK(snprintf(number, sizeof number, "%-8d", gid), sizeof number)) {        _EXIT(EXIT_FAILURE);    }    return number;}#elseconst char *getname(const uid_t uid){    struct userid *p;    struct passwd *pwd = NULL;    for (p = user_head; p; p = p->next) {        if (p->uid == uid) {            return p->name;        }    }    if (# ifndef ALWAYS_RESOLVE_IDS        chrooted == 0 && # endif        authresult.slow_tilde_expansion == 0) {        pwd = getpwuid(uid);    }    if ((p = malloc(sizeof *p)) == NULL) {        die_mem();    }    p->uid = uid;    if ((p->name = malloc((size_t) 9U)) == NULL) {        die_mem();    }    if (pwd != NULL) {        if (SNCHECK(snprintf(p->name, (size_t) 9U,                              "%-8.8s", pwd->pw_name), (size_t) 9U)) {            _EXIT(EXIT_FAILURE);        }    } else {        if (SNCHECK(snprintf(p->name, (size_t) 9U, "%-8d", uid),                     (size_t) 9U)) {            _EXIT(EXIT_FAILURE);        }    }    p->next = user_head;    user_head = p;        return p->name;}/* eeeehm... sorry for names, ya know copy&paste :))) */const char *getgroup(const gid_t gid){    struct groupid *p;    struct group *pwd = NULL;    for (p = group_head; p; p = p->next) {        if (p->gid == gid) {            return p->name;        }    } # ifndef ALWAYS_RESOLVE_IDS       if (chrooted == 0) # endif    {        pwd = getgrgid(gid);    }    if ((p = malloc(sizeof *p)) == NULL) {        die_mem();    }    p->gid = gid;    if ((p->name = malloc((size_t) 9U)) == NULL) {        die_mem();    }    if (pwd != NULL) {        if (SNCHECK(snprintf(p->name, (size_t) 9U, "%-8.8s",                             pwd->gr_name), (size_t) 9U)) {            _EXIT(EXIT_FAILURE);        }    } else {        if (SNCHECK(snprintf(p->name, (size_t) 9U, "%-8d", gid),                     (size_t) 9U)) {            _EXIT(EXIT_FAILURE);        }    }    p->next = group_head;    group_head = p;        return p->name;}#endifstatic void addfile(const char *name, const char *suffix){    struct filename *p;    unsigned int l;    if (!name || !suffix) {        return;    }    if (matches >= max_ls_files) {        return;    }    matches++;    l = (unsigned int) (strlen(name) + strlen(suffix));    if (l > colwidth) {        colwidth = l;    }    if ((p = malloc(offsetof(struct filename, line) + l + 1U)) == NULL) {        return;    }    if (SNCHECK(snprintf(p->line, l + 1U, "%s%s", name, suffix), l + 1U)) {        _EXIT(EXIT_FAILURE);    }    if (tail != NULL) {        tail->down = p;    } else {        head = p;    }    tail = p;    filenames++;}/* listfile returns non-zero if the file is a directory */static int listfile(const FileInfo * const fi,  const char *name){    int rval = 0;    struct stat st;    struct tm *t;    char suffix[2] = { 0, 0 };    char m[MAXPATHLEN + 1U];    #ifndef MINIMAL    if (modern_listings != 0) {        const char *n;        char *alloca_nameline;        const size_t sizeof_nameline = MAXPATHLEN + 256U;        if (fi == NULL) {            n = name;        } else {            n = FI_NAME(fi);        }        if ((alloca_nameline = ALLOCA(sizeof_nameline)) == NULL) {            return 0;        }        if ((rval = modernformat(n, alloca_nameline, sizeof_nameline)) < 0) {            ALLOCA_FREE(alloca_nameline);                        return 0;        }        addfile(alloca_nameline, suffix);        ALLOCA_FREE(alloca_nameline);                return rval;    }#endif    if (fi == NULL) {        if (lstat(name, &st) < 0) {            return 0;        }        } else {        st.st_size = fi->size;        st.st_mtime = fi->mtime;                st.st_mode = fi->mode;        st.st_nlink = fi->nlink;                st.st_uid = fi->uid;        st.st_gid = fi->gid;        name = FI_NAME(fi);    }#if defined(WITH_VIRTUAL_CHROOT) && defined(S_IFLNK) && defined(S_IFDIR)    if (S_ISLNK(st.st_mode) && name[0] == '.' && name[1] == '.' && name[2] == 0) {        st.st_mode &= ~S_IFLNK;        st.st_mode |= S_IFDIR;    }  /* Hack to please some Windows client that dislike ../ -> ../ */#endif#ifdef DISPLAY_FILES_IN_UTC_TIME    t = gmtime((time_t *) &st.st_mtime);#else    t = localtime((time_t *) &st.st_mtime);#endif    if (t == NULL) {        logfile(LOG_ERR, "{gm,local}gtime() for [%s]", name);        return 0;    }    if (opt_F) {        if (S_ISLNK(st.st_mode))            suffix[0] = '@';        else if (S_ISDIR(st.st_mode)) {            suffix[0] = '/';            rval = 1;        } else if (st.st_mode & 010101) {            suffix[0] = '*';        }    }    if (opt_l) {        strncpy(m, " ---------", (sizeof m) - (size_t) 1U);        m[(sizeof m) - (size_t) 1U] = 0;        switch (st.st_mode & S_IFMT) {        case S_IFREG:            m[0] = '-';            break;        case S_IFLNK:            m[0] = 'l';            break;            /* readlink() here? */        case S_IFDIR:            m[0] = 'd';            rval = 1;            break;        }        if (m[0] != ' ') {            char *alloca_nameline;            const size_t sizeof_nameline = MAXPATHLEN + MAXPATHLEN + 128U;            char timeline[6U];                        if (st.st_mode & 0400) {                m[1] = 'r';            }            if (st.st_mode & 0200) {                m[2] = 'w';            }            if (st.st_mode & 0100) {                m[3] = (char) (st.st_mode & 04000 ? 's' : 'x');            } else if (st.st_mode & 04000) {                m[3] = 'S';            }            if (st.st_mode & 040) {                m[4] = 'r';            }            if (st.st_mode & 020) {                m[5] = 'w';            }            if (st.st_mode & 010) {                m[6] = (char) (st.st_mode & 02000 ? 's' : 'x');            } else if (st.st_mode & 02000) {                m[6] = 'S';            }            if (st.st_mode & 04) {                m[7] = 'r';            }            if (st.st_mode & 02) {                m[8] = 'w';            }            if (st.st_mode & 01) {                m[9] = (char) (st.st_mode & 01000 ? 't' : 'x');            } else if (st.st_mode & 01000) {                m[9] = 'T';            }                        if (time(NULL) - st.st_mtime > 180 * 24 * 60 * 60) {                if (SNCHECK(snprintf(timeline, sizeof timeline, "%5d",                                     t->tm_year + 1900), sizeof timeline)) {                    _EXIT(EXIT_FAILURE);                }            } else {                if (SNCHECK(snprintf(timeline, sizeof timeline, "%02d:%02d",                                     t->tm_hour, t->tm_min), sizeof timeline)) {                    _EXIT(EXIT_FAILURE);                }            }            if ((alloca_nameline = ALLOCA(sizeof_nameline)) == NULL) {                return 0;            }#ifdef WITH_LARGE_FILES            if (SNCHECK(snprintf(alloca_nameline, sizeof_nameline,                                 "%s %4d %s %s %8llu %s %2d %s %s",                                  m, st.st_nlink, getname(st.st_uid),                                 getgroup(st.st_gid),                                  (unsigned long long) st.st_size,                                 months[t->tm_mon],                                 t->tm_mday, timeline, name),                        sizeof_nameline))#else            if (SNCHECK(snprintf(alloca_nameline, sizeof_nameline,                                 "%s %4d %s %s %8lu %s %2d %s %s",                                  m, st.st_nlink, getname(st.st_uid),                                 getgroup(st.st_gid),                                  (unsigned long) st.st_size,                                 months[t->tm_mon],                                 t->tm_mday, timeline, name),                        sizeof_nameline))#endif            {                ALLOCA_FREE(alloca_nameline);                _EXIT(EXIT_FAILURE);            }            if (S_ISLNK(st.st_mode)) {                char *p = alloca_nameline + strlen(alloca_nameline);                                {                    int sx;                                        if ((sx = readlink(name, m, sizeof m - 1U)) > 0) {                        m[sx] = 0;                    } else {                        m[0] = m[1] = '.';                        m[2] = 0;                    }                }                suffix[0] = 0;                if (opt_F && stat(name, &st) == 0) {                    if (S_ISLNK(st.st_mode)) {                        suffix[0] = '@';                    } else if (S_ISDIR(st.st_mode)) {                        suffix[0] = '/';                    } else if (st.st_mode & 010101) {                        suffix[0] = '*';                    }                }                /* 2 * MAXPATHLEN + gap should be enough, but be paranoid... */                if (SNCHECK                    (snprintf(p, (sizeof_nameline) - strlen(alloca_nameline),                              " -> %s", m),                      (sizeof_nameline) - strlen(alloca_nameline))) {                    ALLOCA_FREE(alloca_nameline);                                        _EXIT(EXIT_FAILURE);                }            }            addfile(alloca_nameline, suffix);            ALLOCA_FREE(alloca_nameline);                    }                    /* hide non-downloadable files */    } else {                if (S_ISREG(st.st_mode) ||            S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) {            addfile(name, suffix);        }    }    return rval;}static void outputfiles(int f){    unsigned int n;    struct filename *p;    struct filename *q;    if (!head) {        return;    }    tail->down = NULL;    tail = NULL;    colwidth = (colwidth | 7U) + 1U;    if (opt_l != 0 || opt_C == 0) {        colwidth = 75U;    }    /* set up first column */    p = head;    p->top = 1;    if (colwidth > 75U) {        n = filenames;    } else {        n = (filenames + (75U / colwidth) - 1U) / (75U / colwidth);    }    while (n && p) {        p = p->down;        if (p != NULL) {            p->top = 0;        }        n--;    }    /* while there's a neighbour to the right, point at it */    q = head;    while (p) {        p->top = q->top;        q->right = p;        q = q->down;        p = p->down;    }    /* some are at the right end */    while (q) {        q->right = NULL;        q = q->down;    }    /* don't want wraparound, do we? */    p = head;    while (p && p->down && !p->down->top) {        p = p->down;    }    if (p && p->down) {        p->down = NULL;    }    /* print each line, which consists of each column */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -