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

📄 ftp-ls.c

📁 Wget很好的处理了http和ftp的下载,很值得学习的经典代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      tok = strtok(NULL,  ":");      if (tok == NULL) continue;      hour = atoi(tok);      tok = strtok(NULL,  "M");      if (tok == NULL) continue;      min = atoi(tok);      /* Adjust hour from AM/PM. Just for the record, the sequence goes         11:00AM, 12:00PM, 01:00PM ... 11:00PM, 12:00AM, 01:00AM . */      tok+=2;      if (hour == 12)  hour  = 0;      if (*tok == 'P') hour += 12;      DEBUGP(("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n",               year+1900, month, day, hour, min));            /* Build the time-stamp (copy & paste from above) */      timestruct.tm_sec   = 0;      timestruct.tm_min   = min;      timestruct.tm_hour  = hour;      timestruct.tm_mday  = day;      timestruct.tm_mon   = month;      timestruct.tm_year  = year;      timestruct.tm_wday  = 0;      timestruct.tm_yday  = 0;      timestruct.tm_isdst = -1;      cur.tstamp = mktime (&timestruct); /* store the time-stamp */      DEBUGP(("Timestamp: %ld\n", cur.tstamp));      /* Third column: Either file length, or <DIR>. We also set the         permissions (guessed as 0644 for plain files and 0755 for         directories as the listing does not give us a clue) and filetype         here. */      tok = strtok(NULL, " ");      if (tok == NULL) continue;      while ((tok != NULL) && (*tok == '\0'))  tok = strtok(NULL, " ");      if (tok == NULL) continue;      if (*tok == '<')        {          cur.type  = FT_DIRECTORY;          cur.size  = 0;          cur.perms = 0755;          DEBUGP(("Directory\n"));        }      else        {          wgint size;          cur.type  = FT_PLAINFILE;          errno = 0;          size = str_to_wgint (tok, NULL, 10);          if (size == WGINT_MAX && errno == ERANGE)            cur.size = 0;       /* overflow */          else            cur.size = size;          cur.perms = 0644;          DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));        }      cur.linkto = NULL;      /* And put everything into the linked list */      if (!dir)        {          l = dir = xnew (struct fileinfo);          memcpy (l, &cur, sizeof (cur));          l->prev = l->next = NULL;        }      else        {          cur.prev = l;          l->next = xnew (struct fileinfo);          l = l->next;          memcpy (l, &cur, sizeof (cur));          l->next = NULL;        }      xfree (line);    }  fclose(fp);  return dir;}/* Converts VMS symbolic permissions to number-style ones, e.g. string   RWED,RWE,RE to 755. "D" (delete) is taken to be equal to "W"   (write). Inspired by a patch of Stoyan Lekov <lekov@eda.bg>. */static intvmsperms (const char *s){  int perms = 0;  do    {      switch (*s) {        case ',': perms <<= 3; break;        case 'R': perms  |= 4; break;        case 'W': perms  |= 2; break;        case 'D': perms  |= 2; break;        case 'E': perms  |= 1; break;        default:  DEBUGP(("wrong VMS permissons!\n"));       }    }  while (*++s);  return perms;}static struct fileinfo *ftp_parse_vms_ls (const char *file){  FILE *fp;  /* #### A third copy of more-or-less the same array ? */  static const char *months[] = {    "JAN", "FEB", "MAR", "APR", "MAY", "JUN",    "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"  };  int i;  int year, month, day;          /* for time analysis */  int hour, min, sec;  struct tm timestruct;  char *line, *tok;              /* tokenizer */  struct fileinfo *dir, *l, cur; /* list creation */  fp = fopen (file, "rb");  if (!fp)    {      logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));      return NULL;    }  dir = l = NULL;  /* Skip empty line. */  line = read_whole_line (fp);  xfree_null (line);  /* Skip "Directory PUB$DEVICE[PUB]" */  line = read_whole_line (fp);  xfree_null (line);  /* Skip empty line. */  line = read_whole_line (fp);  xfree_null (line);  /* Line loop to end of file: */  while ((line = read_whole_line (fp)) != NULL)    {      char *p;      i = clean_line (line);      if (!i)        {          xfree (line);          break;        }      /* First column: Name. A bit of black magic again. The name my be         either ABCD.EXT or ABCD.EXT;NUM and it might be on a separate         line. Therefore we will first try to get the complete name         until the first space character; if it fails, we assume that the name         occupies the whole line. After that we search for the version         separator ";", we remove it and check the extension of the file;         extension .DIR denotes directory. */      tok = strtok(line, " ");      if (tok == NULL) tok = line;      DEBUGP(("file name: '%s'\n", tok));      for (p = tok ; *p && *p != ';' ; p++)        ;      if (*p == ';') *p = '\0';      p   = tok + strlen(tok) - 4;      if (!strcmp(p, ".DIR")) *p = '\0';      cur.name = xstrdup(tok);      DEBUGP(("Name: '%s'\n", cur.name));      /* If the name ends on .DIR or .DIR;#, it's a directory. We also set         the file size to zero as the listing does tell us only the size in         filesystem blocks - for an integrity check (when mirroring, for         example) we would need the size in bytes. */            if (! *p)        {          cur.type  = FT_DIRECTORY;          cur.size  = 0;          DEBUGP(("Directory\n"));        }      else        {          cur.type  = FT_PLAINFILE;          DEBUGP(("File\n"));        }      cur.size  = 0;      /* Second column, if exists, or the first column of the next line         contain file size in blocks. We will skip it. */      tok = strtok(NULL, " ");      if (tok == NULL)       {        DEBUGP(("Getting additional line\n"));        xfree (line);        line = read_whole_line (fp);        if (!line)        {          DEBUGP(("empty line read, leaving listing parser\n"));          break;        }        i = clean_line (line);        if (!i)         {          DEBUGP(("confusing VMS listing item, leaving listing parser\n"));          xfree (line);          break;        }        tok = strtok(line, " ");      }      DEBUGP(("second token: '%s'\n", tok));      /* Third/Second column: Date DD-MMM-YYYY. */      tok = strtok(NULL, "-");      if (tok == NULL) continue;      DEBUGP(("day: '%s'\n",tok));      day = atoi(tok);      tok = strtok(NULL, "-");      if (!tok)      {        /* If the server produces garbage like           'EA95_0PS.GZ;1      No privilege for attempted operation'           the first strtok(NULL, "-") will return everything until the end           of the line and only the next strtok() call will return NULL. */        DEBUGP(("nonsense in VMS listing, skipping this line\n"));        xfree (line);        break;      }      for (i=0; i<12; i++) if (!strcmp(tok,months[i])) break;      /* Uknown months are mapped to January */      month = i % 12 ;       tok = strtok (NULL, " ");      if (tok == NULL) continue;      year = atoi (tok) - 1900;      DEBUGP(("date parsed\n"));      /* Fourth/Third column: Time hh:mm[:ss] */      tok = strtok (NULL, " ");      if (tok == NULL) continue;      min = sec = 0;      p = tok;      hour = atoi (p);      for (; *p && *p != ':'; ++p)        ;      if (*p)        min = atoi (++p);      for (; *p && *p != ':'; ++p)        ;      if (*p)        sec = atoi (++p);      DEBUGP(("YYYY/MM/DD HH:MM:SS - %d/%02d/%02d %02d:%02d:%02d\n",               year+1900, month, day, hour, min, sec));            /* Build the time-stamp (copy & paste from above) */      timestruct.tm_sec   = sec;      timestruct.tm_min   = min;      timestruct.tm_hour  = hour;      timestruct.tm_mday  = day;      timestruct.tm_mon   = month;      timestruct.tm_year  = year;      timestruct.tm_wday  = 0;      timestruct.tm_yday  = 0;      timestruct.tm_isdst = -1;      cur.tstamp = mktime (&timestruct); /* store the time-stamp */      DEBUGP(("Timestamp: %ld\n", cur.tstamp));      /* Skip the fifth column */      tok = strtok(NULL, " ");      if (tok == NULL) continue;      /* Sixth column: Permissions */      tok = strtok(NULL, ","); /* Skip the VMS-specific SYSTEM permissons */      if (tok == NULL) continue;      tok = strtok(NULL, ")");      if (tok == NULL)        {          DEBUGP(("confusing VMS permissions, skipping line\n"));          xfree (line);          continue;        }      /* Permissons have the format "RWED,RWED,RE" */      cur.perms = vmsperms(tok);      DEBUGP(("permissions: %s -> 0%o\n", tok, cur.perms));      cur.linkto = NULL;      /* And put everything into the linked list */      if (!dir)        {          l = dir = xnew (struct fileinfo);          memcpy (l, &cur, sizeof (cur));          l->prev = l->next = NULL;        }      else        {          cur.prev = l;          l->next = xnew (struct fileinfo);          l = l->next;          memcpy (l, &cur, sizeof (cur));          l->next = NULL;        }      xfree (line);    }  fclose (fp);  return dir;}/* This function switches between the correct parsing routine depending on   the SYSTEM_TYPE. The system type should be based on the result of the   "SYST" response of the FTP server. According to this repsonse we will   use on of the three different listing parsers that cover the most of FTP   servers used nowadays.  */struct fileinfo *ftp_parse_ls (const char *file, const enum stype system_type){  switch (system_type)    {    case ST_UNIX:      return ftp_parse_unix_ls (file, 0);    case ST_WINNT:      {        /* Detect whether the listing is simulating the UNIX format */        FILE *fp;        int   c;        fp = fopen (file, "rb");        if (!fp)        {          logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));          return NULL;        }        c = fgetc(fp);        fclose(fp);        /* If the first character of the file is '0'-'9', it's WINNT           format. */        if (c >= '0' && c <='9')          return ftp_parse_winnt_ls (file);        else          return ftp_parse_unix_ls (file, 1);      }    case ST_VMS:      return ftp_parse_vms_ls (file);    case ST_MACOS:      return ftp_parse_unix_ls (file, 1);    default:      logprintf (LOG_NOTQUIET, _("\Unsupported listing type, trying Unix listing parser.\n"));      return ftp_parse_unix_ls (file, 0);    }}/* Stuff for creating FTP index. *//* The function creates an HTML index containing references to given   directories and files on the appropriate host.  The references are   FTP.  */uerr_tftp_index (const char *file, struct url *u, struct fileinfo *f){  FILE *fp;  char *upwd;  char *htclfile;               /* HTML-clean file name */  if (!output_stream)    {      fp = fopen (file, "wb");      if (!fp)        {          logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));          return FOPENERR;        }    }  else    fp = output_stream;  if (u->user)    {      char *tmpu, *tmpp;        /* temporary, clean user and passwd */      tmpu = url_escape (u->user);      tmpp = u->passwd ? url_escape (u->passwd) : NULL;      if (tmpp)        upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0);      else        upwd = concat_strings (tmpu, "@", (char *) 0);      xfree (tmpu);      xfree_null (tmpp);    }  else    upwd = xstrdup ("");  fprintf (fp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");  fprintf (fp, "<html>\n<head>\n<title>");  fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);  fprintf (fp, "</title>\n</head>\n<body>\n<h1>");  fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);  fprintf (fp, "</h1>\n<hr>\n<pre>\n");  while (f)    {      fprintf (fp, "  ");      if (f->tstamp != -1)        {          /* #### Should we translate the months?  Or, even better, use             ISO 8601 dates?  */          static const char *months[] = {            "Jan", "Feb", "Mar", "Apr", "May", "Jun",            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"          };          struct tm *ptm = localtime ((time_t *)&f->tstamp);          fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],                  ptm->tm_mday);          if (ptm->tm_hour)            fprintf (fp, "%02d:%02d  ", ptm->tm_hour, ptm->tm_min);          else            fprintf (fp, "       ");        }      else        fprintf (fp, _("time unknown       "));      switch (f->type)        {        case FT_PLAINFILE:          fprintf (fp, _("File        "));          break;        case FT_DIRECTORY:          fprintf (fp, _("Directory   "));          break;        case FT_SYMLINK:          fprintf (fp, _("Link        "));          break;        default:          fprintf (fp, _("Not sure    "));          break;        }      htclfile = html_quote_string (f->name);      fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port);      if (*u->dir != '/')        putc ('/', fp);      fprintf (fp, "%s", u->dir);      if (*u->dir)        putc ('/', fp);      fprintf (fp, "%s", htclfile);      if (f->type == FT_DIRECTORY)        putc ('/', fp);      fprintf (fp, "\">%s", htclfile);      if (f->type == FT_DIRECTORY)        putc ('/', fp);      fprintf (fp, "</a> ");      if (f->type == FT_PLAINFILE)        fprintf (fp, _(" (%s bytes)"), number_to_static_string (f->size));      else if (f->type == FT_SYMLINK)        fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");      putc ('\n', fp);      xfree (htclfile);      f = f->next;    }  fprintf (fp, "</pre>\n</body>\n</html>\n");  xfree (upwd);  if (!output_stream)    fclose (fp);  else    fflush (fp);  return FTPOK;}

⌨️ 快捷键说明

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