Example #1
0
rdirectory *ssh_read_directory(const char *path)
{
	rdirectory *rdir;
	int i;
	SFTP_DIRENT **dir;
	char *p = ftp_path_absolute(path);
	stripslash(p);

	if(ssh_readdir(p, &dir) != 0) {
		free(p);
		return 0;
	}

	rdir = rdir_create();

	ftp_trace("*** start parsing directory listing ***\n");

	for(i = 0; dir[i]; i++) {
		rfile *rf;
		char *e, *cf = dir[i]->longname;

		ftp_trace("%s\n", dir[i]->longname);

		rf = rfile_create();

		rf->perm = perm2string(dir[i]->a.perm);

		e = strqsep(&cf, ' ');  /* skip permissions */
		e = strqsep(&cf, ' ');  /* nhl? */
/*		if(ftp->ssh_version > 2) {*/
			rf->nhl = atoi(e);
/*		} else*/
/*			rf->nhl = 0;*/
#if 1
		e = strqsep(&cf, ' ');
		rf->owner = xstrdup(e);
		e = strqsep(&cf, ' ');
		rf->group = xstrdup(e);
#else
		asprintf(&rf->owner, "%d", dir[i]->a.uid);
		asprintf(&rf->group, "%d", dir[i]->a.gid);
#endif

		asprintf(&rf->path, "%s/%s", p, dir[i]->filename);
		rf->mtime = dir[i]->a.mtime;
		if(rf->mtime == 0) {
			char *m, *d, *y;
			while(e && month_number(e) == -1)
				e = strqsep(&cf, ' ');
			if(e) {
				m = e;
				d = strqsep(&cf, ' ');
				y = strqsep(&cf, ' ');
				ftp_trace("parsing time: m:%s d:%s y:%s\n", m, d, y);
				rfile_parse_time(rf, m, d, y);
			}
		}
		rf->date = time_to_string(rf->mtime);
		rf->size = dir[i]->a.size;
		rfile_parse_colors(rf);

		rf->link = 0;
		if(rislink(rf) && ftp->ssh_version > 2)
			rf->link = ssh_readlink(rf->path);

		list_additem(rdir->files, (void *)rf);
	}
	ftp_trace("*** end parsing directory listing ***\n");

	ssh_free_dirents(dir);

	rdir->path = p;

	ftp_trace("added directory '%s' to cache\n", p);
	list_additem(ftp->cache, rdir);

	return rdir;
}
Example #2
0
/* This is a total mess!
 */
static int rfile_parse_unix(rfile *f, char *str, const char *dirpath)
{
    char *cf;
    char *e;
    char *m=0, *d=0, *y=0;
    char *saved_field[5];
    bool time_parsed = false;

    /* real unix ls listing:
     *
     * saved_field[0] == nhl
     * saved_field[1] == owner
     * saved_field[2] == group
     * saved_field[3] == size
     * saved_field[4] == month
     *
     *
     * unix w/o group listing:
     *
     * saved_field[0] == nhl
     * saved_field[1] == owner
     * saved_field[2] == size
     * saved_field[3] == month
     * saved_field[4] == date
     *
     *
     * strange MacOS WebStar thingy:
     *
     * saved_field[0] == size or "folder"
     * saved_field[1] == zero or date if [0]=="folder"
     * saved_field[2] == size (again!?) or month
     * saved_field[3] == month or date
     * saved_field[4] == date or time (or year?)
     *
     *
     * Linux netkit FTP server with LANG=sv_SE (ISO date&time format):
     * (-rw-------    1 mhe      mhe          1422 2002-09-24 22:30 asdf.txt)
     *
     * saved_field[0] == nhl
     * saved_field[1] == owner
     * saved_field[2] == group
     * saved_field[3] == size
     * saved_field[4] == YYYY-MM-DD
     *
     */

    if(strncmp(str, "total ", 6) == 0)
        return 1;
    if(strncmp(str, "insgesamt ", 10) == 0)    // de "overall"
        return 1;

    cf = str;

/*  NEXT_FIELD;
    f->perm = xstrdup(e);*/
    /* the above doesn't work here:
     * drwxrwxr-x156 31       20          29696 Apr 26 19:00 gnu
     * ----------^
     * so we assume the permission string is exactly 10 characters
     */
    f->perm = xstrndup(cf, 10);
    cf += 10;

    /* drwxr-s---+ 78 0        228         1536 Jul 10 15:36 private
     */
    if(*cf == '+')
       ++cf;

    NEXT_FIELD;
    saved_field[0] = xstrdup(e);

    NEXT_FIELD;
    saved_field[1] = xstrdup(e);

    NEXT_FIELD;
    saved_field[2] = xstrdup(e);

    NEXT_FIELD;
    /* special device? */
    if(e[strlen(e)-1] == ',') {
        NEXT_FIELD;
    }
    saved_field[3] = xstrdup(e);

    NEXT_FIELD;
    saved_field[4] = xstrdup(e);

    /* distinguish the different ls variants by looking
     * for the month field
     */

    if(month_number(saved_field[4]) != -1)
    {
        /* ls -l */
        f->nhl = atoi(saved_field[0]);
        free(saved_field[0]);
        f->owner = saved_field[1];
        f->group = saved_field[2];
        f->size = strtoull(saved_field[3],NULL,10);
        free(saved_field[3]);
        m = saved_field[4];
        NEXT_FIELD2;
        d = xstrdup(e);
        NEXT_FIELD2;
        y = xstrdup(e);
    } else if(month_number(saved_field[3]) != -1)
    {
        /* ls -lG */
        f->nhl = atoi(saved_field[0]);
        free(saved_field[0]);
        f->owner = saved_field[1];
        f->group = xstrdup("group");
        f->size = strtoull(saved_field[2],NULL,10);
        free(saved_field[2]);
        m = saved_field[3];
        d = saved_field[4];
        NEXT_FIELD2;
        y = xstrdup(e);
    } else if(month_number(saved_field[2]) != -1)
    {
        free(saved_field[0]);
        f->nhl = 0;
        f->owner = xstrdup("owner");;
        f->group = xstrdup("group");
        f->size = strtoull(saved_field[1],NULL,10);
        free(saved_field[1]);
        m = saved_field[2];
        d = saved_field[3];
        y = saved_field[4];
    } else {
        int iy, im, id, ih = 0, imin = 0;
        if(sscanf(saved_field[4], "%d-%d-%d", &iy, &im, &id) == 3) {
            /* date on the form YYYY-MM-DD */
            im -= 1; /* should be 0-based */

            f->nhl = atoi(saved_field[0]);
            free(saved_field[0]);
            f->owner = saved_field[1];
            f->group = saved_field[2];
            f->size = strtoull(saved_field[3],NULL,10);
            free(saved_field[3]);
            free(saved_field[4]);

            e = strqsep(&cf, ' '); /* HH:MM */
            sscanf(e, "%d:%d", &ih, &imin);

            {
                struct tm mt;
                time_t now;

                f->mtime = (time_t)-1;

                mt.tm_sec = 0;
                mt.tm_min = imin;
                mt.tm_hour = ih;
                mt.tm_mday = id;
                mt.tm_mon = im;
                mt.tm_year = iy;
                mt.tm_isdst = -1;

                f->mtime = mktime(&mt);

                time(&now);

                bool success = true;
                if(f->mtime != (time_t)-1 &&
                   (now > f->mtime + 6L * 30L * 24L * 60L * 60L  /* Old. */
                    || now < f->mtime - 60L * 60L))   /* In the future. */
                {
                    success = asprintf(&f->date, "%s %2d %5d", month_name[im], id, iy) != -1;
                } else {
                    success = asprintf(&f->date, "%s %2d %02d:%02d", month_name[im], id, ih, imin) != -1;
                }
                if (!success)
                {
                  f->date = NULL;
                  return -1;
                }

                time_parsed = true;
            }
        } else {
            free(saved_field[0]);
            free(saved_field[1]);
            free(saved_field[2]);
            free(saved_field[3]);
            free(saved_field[4]);
            return -1;
        }
    }

    if(!time_parsed) {
        if (asprintf(&f->date, "%s %2s %5s", m, d, y) == -1)
        {
          free(m);
          free(d);
          free(y);
          f->date = NULL;
          return -1;
        }
        rfile_parse_time(f, m, d, y);
        if(f->mtime == (time_t)-1)
            ftp_trace("rfile_parse_time failed! date == '%s'\n", f->date);
        free(m);
        free(d);
        free(y);
    }

    if(!cf)
        return -1;

    e = strstr(cf, " -> ");
    if(e) {
        *e = 0;
        f->link = xstrdup(e+4);
    }


    if (asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", cf) == -1)
    {
      f->path = NULL;
      return -1;
    }

    rfile_parse_colors(f);

    return 0;
}