/*
** Copyright 2000-2004 University of Illinois Board of Trustees
** Copyright 2000-2004 Mark D. Roth
** All rights reserved.
**
** list_parse_eplf.c - EPLF-style FTP directory parsing code
**
** Mark D. Roth <roth@feep.net>
*/
#include <internal.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
/*
** parse EPLF directories
**
** EPLF format documented here:
** http://cr.yp.to/ftp/list/eplf.html
*/
int
_ftp_list_parse_eplf(FTP *ftp, char *buf, file_info_t *fip)
{
char *fieldp, *nextp;
unsigned long ul;
unsigned int ui;
#ifdef DEBUG
printf("==> _ftp_list_parse_eplf(ftp=0x%lx (%s), buf=0x%lx, "
"fip=0x%lx)\n",
ftp, ftp->ftp_host, buf, fip);
#endif
/* skip leading '+' */
if (buf[0] != '+')
{
errno = EINVAL;
return FLP_ERROR;
}
nextp = buf + 1;
/* extract filename */
fieldp = strchr(nextp, '\t');
if (fieldp == NULL)
{
errno = EINVAL;
return FLP_ERROR;
}
*fieldp++ = '\0';
strlcpy(fip->fi_filename, fieldp, sizeof(fip->fi_filename));
/* parse facts */
while ((fieldp = strsep(&nextp, ",")) != NULL)
{
if (*fieldp == '\0')
continue;
switch (*fieldp)
{
case 'r': /* RETR may succeed */
fip->fi_stat.fs_mode |= S_IFREG;
continue;
case '/': /* CWD may succeed */
fip->fi_stat.fs_mode |= S_IFDIR;
continue;
case 's': /* file size */
sscanf(fieldp + 1, "%lu", &ul);
fip->fi_stat.fs_size = (off_t)ul;
continue;
case 'm': /* mtime */
sscanf(fieldp + 1, "%lu", &ul);
fip->fi_stat.fs_mtime = (time_t)ul;
continue;
case 'u': /* "up" - file mode */
/* if it's not "up", treat as an unknown fact */
if (fieldp[1] != 'p')
continue;
sscanf(fieldp + 2, "%lo", &ui);
fip->fi_stat.fs_mode |= (mode_t)ui;
continue;
default: /* unknown fact */
break;
}
/* otherwise, unknown fact, so just ignore it */
}
/* EPLF doesn't encode these fields at all, so set defaults */
strlcpy(fip->fi_stat.fs_username, "-1",
sizeof(fip->fi_stat.fs_username));
strlcpy(fip->fi_stat.fs_groupname, "-1",
sizeof(fip->fi_stat.fs_groupname));
fip->fi_stat.fs_nlink = 1;
#ifdef DEBUG
printf("<== _ftp_list_parse_eplf(): success\n");
#endif
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1