~ubuntu-branches/ubuntu/precise/wget/precise-proposed

« back to all changes in this revision

Viewing changes to src/ftp-ls.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-10-19 00:00:09 UTC
  • mfrom: (2.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20111019000009-8p33w3wz4b1rdri0
Tags: 1.13-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add wget-udeb to ship wget.gnu as alternative to busybox wget
    implementation.
  - Depend on libssl-dev 0.9.8k-7ubuntu4 (LP: #503339)
* Dropped changes, superseded in Debian:
  - Keep build dependencies in main:
    + debian/control: remove info2man build-dep
    + debian/patches/series: disable wget-infopod_generated_manpage
  - Mark wget Multi-Arch: foreign, so packages that aren't of the same arch
    can depend on it.
* Pass --with-ssl=openssl; we don't want to use gnutls, there's no udeb for
  it.
* Add a second build pass for the udeb, so we can build without libidn.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Parsing FTP `ls' output.
2
2
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
 
   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
3
   2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
 
4
   Inc.
4
5
 
5
6
This file is part of GNU Wget.
6
7
 
33
34
#include <stdio.h>
34
35
#include <stdlib.h>
35
36
#include <string.h>
36
 
#ifdef HAVE_UNISTD_H
37
 
# include <unistd.h>
38
 
#endif
 
37
#include <unistd.h>
39
38
#include <errno.h>
40
39
#include <time.h>
41
40
#include "utils.h"
100
99
  };
101
100
  int next, len, i, error, ignore;
102
101
  int year, month, day;         /* for time analysis */
103
 
  int hour, min, sec;
 
102
  int hour, min, sec, ptype;
104
103
  struct tm timestruct, *tnow;
105
104
  time_t timenow;
106
105
 
183
182
                                   treated equally for now.  */
184
183
      year = hour = min = sec = 0; /* Silence the compiler.  */
185
184
      month = day = 0;
 
185
      ptype = TT_DAY;
186
186
      next = -1;
187
187
      /* While there are tokens on the line, parse them.  Next is the
188
188
         number of tokens left until the filename.
262
262
                      /* This means these were hours!  */
263
263
                      hour = year;
264
264
                      year = 0;
 
265
                      ptype = TT_HOUR_MIN;
265
266
                      ++tok;
266
267
                      /* Get the minutes...  */
267
268
                      for (; c_isdigit (*tok); tok++)
414
415
      timestruct.tm_yday  = 0;
415
416
      timestruct.tm_isdst = -1;
416
417
      l->tstamp = mktime (&timestruct); /* store the time-stamp */
 
418
      l->ptype = ptype;
417
419
 
418
420
      xfree (line);
419
421
    }
453
455
         column 39 of the listing. This way we could also recognize
454
456
         filenames that begin with a series of space characters (but who
455
457
         really wants to use such filenames anyway?). */
456
 
      if (len < 40) continue;
 
458
      if (len < 40) goto continue_loop;
457
459
      tok = line + 39;
458
460
      cur.name = xstrdup(tok);
459
 
      DEBUGP(("Name: '%s'\n", cur.name));
 
461
      DEBUGP (("Name: '%s'\n", cur.name));
460
462
 
461
463
      /* First column: mm-dd-yy. Should atoi() on the month fail, january
462
464
         will be assumed.  */
463
465
      tok = strtok(line, "-");
464
 
      if (tok == NULL) continue;
 
466
      if (tok == NULL) goto continue_loop;
465
467
      month = atoi(tok) - 1;
466
468
      if (month < 0) month = 0;
467
469
      tok = strtok(NULL, "-");
468
 
      if (tok == NULL) continue;
 
470
      if (tok == NULL) goto continue_loop;
469
471
      day = atoi(tok);
470
472
      tok = strtok(NULL, " ");
471
 
      if (tok == NULL) continue;
 
473
      if (tok == NULL) goto continue_loop;
472
474
      year = atoi(tok);
473
475
      /* Assuming the epoch starting at 1.1.1970 */
474
476
      if (year <= 70) year += 100;
476
478
      /* Second column: hh:mm[AP]M, listing does not contain value for
477
479
         seconds */
478
480
      tok = strtok(NULL,  ":");
479
 
      if (tok == NULL) continue;
 
481
      if (tok == NULL) goto continue_loop;
480
482
      hour = atoi(tok);
481
483
      tok = strtok(NULL,  "M");
482
 
      if (tok == NULL) continue;
 
484
      if (tok == NULL) goto continue_loop;
483
485
      min = atoi(tok);
484
486
      /* Adjust hour from AM/PM. Just for the record, the sequence goes
485
487
         11:00AM, 12:00PM, 01:00PM ... 11:00PM, 12:00AM, 01:00AM . */
487
489
      if (hour == 12)  hour  = 0;
488
490
      if (*tok == 'P') hour += 12;
489
491
 
490
 
      DEBUGP(("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n",
 
492
      DEBUGP (("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n",
491
493
              year+1900, month, day, hour, min));
492
494
 
493
495
      /* Build the time-stamp (copy & paste from above) */
501
503
      timestruct.tm_yday  = 0;
502
504
      timestruct.tm_isdst = -1;
503
505
      cur.tstamp = mktime (&timestruct); /* store the time-stamp */
 
506
      cur.ptype = TT_HOUR_MIN;
504
507
 
505
 
      DEBUGP(("Timestamp: %ld\n", cur.tstamp));
 
508
      DEBUGP (("Timestamp: %ld\n", cur.tstamp));
506
509
 
507
510
      /* Third column: Either file length, or <DIR>. We also set the
508
511
         permissions (guessed as 0644 for plain files and 0755 for
509
512
         directories as the listing does not give us a clue) and filetype
510
513
         here. */
511
514
      tok = strtok(NULL, " ");
512
 
      if (tok == NULL) continue;
 
515
      if (tok == NULL) goto continue_loop;
513
516
      while ((tok != NULL) && (*tok == '\0'))  tok = strtok(NULL, " ");
514
 
      if (tok == NULL) continue;
 
517
      if (tok == NULL) goto continue_loop;
515
518
      if (*tok == '<')
516
519
        {
517
520
          cur.type  = FT_DIRECTORY;
518
521
          cur.size  = 0;
519
522
          cur.perms = 0755;
520
 
          DEBUGP(("Directory\n"));
 
523
          DEBUGP (("Directory\n"));
521
524
        }
522
525
      else
523
526
        {
530
533
          else
531
534
            cur.size = size;
532
535
          cur.perms = 0644;
533
 
          DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));
 
536
          DEBUGP (("File, size %s bytes\n", number_to_static_string (cur.size)));
534
537
        }
535
538
 
536
539
      cur.linkto = NULL;
551
554
          l->next = NULL;
552
555
        }
553
556
 
 
557
continue_loop:
554
558
      xfree (line);
555
559
    }
556
560
 
748
752
 
749
753
      tok = strtok(line, " ");
750
754
      if (tok == NULL) tok = line;
751
 
      DEBUGP(("file name:   '%s'\n", tok));
 
755
      DEBUGP (("file name:   '%s'\n", tok));
752
756
 
753
757
      /* Stripping the version number on a VMS system would be wrong.
754
758
         It may be foolish on a non-VMS system, too, but that's someone
762
766
      */
763
767
 
764
768
#if (!defined( __VMS) && !defined( PRESERVE_VMS_VERSIONS))
765
 
      for (p = tok+ strlen( tok); (--p > tok) && c_isdigit( *p); );
 
769
      for (p = tok + strlen (tok); (--p > tok) && c_isdigit( *p); );
766
770
      if ((*p == ';') && (*(p- 1) != '^'))
767
771
        {
768
772
          *p = '\0';
773
777
         Eliminate "^" escape characters from ODS5 extended file name.
774
778
         (A caret is invalid in an ODS2 name, so this is always safe.)
775
779
      */
776
 
      eat_carets( tok);
777
 
      DEBUGP(("file name-^: '%s'\n", tok));
 
780
      eat_carets (tok);
 
781
      DEBUGP (("file name-^: '%s'\n", tok));
778
782
 
779
783
      /* Differentiate between a directory and any other file.  A VMS
780
784
         listing may not include file protections (permissions).  Set a
783
787
         ".DIR;1" file type and version number, as the plain name is
784
788
         what will work in a CWD command.
785
789
      */
786
 
      len = strlen( tok);
787
 
      if (!strncasecmp( (tok+ (len- 4)), ".DIR", 4))
 
790
      len = strlen (tok);
 
791
      if (!strncasecmp((tok + (len - 4)), ".DIR", 4))
788
792
        {
789
 
          *(tok+ (len -= 4)) = '\0'; /* Discard ".DIR". */
 
793
          *(tok+ (len - 4)) = '\0'; /* Discard ".DIR". */
790
794
          cur.type  = FT_DIRECTORY;
791
795
          cur.perms = VMS_DEFAULT_PROT_DIR;
792
 
          DEBUGP(("Directory (nv)\n"));
 
796
          DEBUGP (("Directory (nv)\n"));
793
797
        }
794
 
      else if (!strncasecmp( (tok+ (len- 6)), ".DIR;1", 6))
 
798
      else if (!strncasecmp ((tok + (len - 6)), ".DIR;1", 6))
795
799
        {
796
 
          *(tok+ (len -= 6)) = '\0'; /* Discard ".DIR;1". */
 
800
          *(tok+ (len - 6)) = '\0'; /* Discard ".DIR;1". */
797
801
          cur.type  = FT_DIRECTORY;
798
802
          cur.perms = VMS_DEFAULT_PROT_DIR;
799
 
          DEBUGP(("Directory (v)\n"));
 
803
          DEBUGP (("Directory (v)\n"));
800
804
        }
801
805
      else
802
806
        {
803
807
          cur.type  = FT_PLAINFILE;
804
808
          cur.perms = VMS_DEFAULT_PROT_FILE;
805
 
          DEBUGP(("File\n"));
 
809
          DEBUGP (("File\n"));
806
810
        }
807
 
      cur.name = xstrdup(tok);
808
 
      DEBUGP(("Name: '%s'\n", cur.name));
 
811
      cur.name = xstrdup (tok);
 
812
      DEBUGP (("Name: '%s'\n", cur.name));
809
813
 
810
814
      /* Null the date and time string. */
811
815
      *date_str = '\0';
817
821
         hence useless for an integrity check based on byte-count.
818
822
         Set size to unknown.
819
823
      */
820
 
      cur.size  = 0;
 
824
      cur.size = 0;
821
825
 
822
826
      /* Get token 2, if any.  A long name may force all other data onto
823
827
         a second line.  If needed, read the second line.
824
828
      */
825
829
 
826
 
      tok = strtok(NULL, " ");
 
830
      tok = strtok (NULL, " ");
827
831
      if (tok == NULL)
828
832
        {
829
 
          DEBUGP(("Getting additional line.\n"));
 
833
          DEBUGP (("Getting additional line.\n"));
830
834
          xfree (line);
831
835
          line = read_whole_line (fp);
832
836
          if (!line)
833
837
            {
834
 
              DEBUGP(("EOF.  Leaving listing parser.\n"));
 
838
              DEBUGP (("EOF.  Leaving listing parser.\n"));
835
839
              break;
836
840
            }
837
841
 
839
843
             line (and we may be confused).
840
844
          */
841
845
          if (i <= 0)
842
 
            {
 
846
            {
843
847
              /* Blank line.  End of significant file listing. */
844
 
              DEBUGP(("Blank line.  Leaving listing parser.\n"));
 
848
              DEBUGP (("Blank line.  Leaving listing parser.\n"));
845
849
              xfree (line); /* Free useless line storage. */
846
 
              break;
847
 
            }
 
850
              break;
 
851
            }
848
852
          else if (line[ 0] != ' ')
849
853
            {
850
 
              DEBUGP(("Non-blank in column 1.  Must be a new file name?\n"));
 
854
              DEBUGP (("Non-blank in column 1.  Must be a new file name?\n"));
851
855
              continue;
852
856
            }
853
857
          else
856
860
              if (tok == NULL)
857
861
                {
858
862
                  /* Unexpected non-empty but apparently blank line. */
859
 
                  DEBUGP(("Null token.  Leaving listing parser.\n"));
 
863
                  DEBUGP (("Null token.  Leaving listing parser.\n"));
860
864
                  xfree (line); /* Free useless line storage. */
861
865
                  break;
862
866
                }
871
875
         Time:       HH:MM or HH:MM:SS or HH:MM:SS.CC
872
876
         Owner:      [user] or [user,group]
873
877
         Protection: (ppp,ppp,ppp,ppp) (where "ppp" is "RWED" or some
874
 
                     subset thereof, for System, Owner, Group, World.
 
878
         subset thereof, for System, Owner, Group, World.
875
879
 
876
880
         If permission is lacking, info may be replaced by the string:
877
881
         "No privilege for attempted operation".
878
882
      */
879
883
      while (tok != NULL)
880
 
        {
881
 
          DEBUGP (("Token: >%s<: ", tok));
 
884
        {
 
885
          DEBUGP (("Token: >%s<: ", tok));
882
886
 
883
 
          if ((strlen( tok) < 12) && (strchr( tok, '-') != NULL))
884
 
            {
885
 
              /* Date. */
886
 
              DEBUGP (("Date.\n"));
887
 
              strcpy( date_str, tok);
888
 
              strcat( date_str, " ");
889
 
            }
890
 
          else if ((strlen( tok) < 12) && (strchr( tok, ':') != NULL))
891
 
            {
892
 
              /* Time. */
893
 
              DEBUGP (("Time. "));
894
 
              strncat( date_str,
895
 
               tok,
896
 
               (sizeof( date_str)- strlen( date_str)- 1));
897
 
              DEBUGP (("Date time: >%s<\n", date_str));
898
 
            }
899
 
          else if (strchr( tok, '[') != NULL)
900
 
            {
901
 
              /* Owner.  (Ignore.) */
902
 
              DEBUGP (("Owner.\n"));
903
 
            }
904
 
          else if (strchr( tok, '(') != NULL)
905
 
            {
906
 
              /* Protections (permissions). */
907
 
              perms = 0;
908
 
              j = 0;
909
 
              for (i = 0; i < strlen( tok); i++)
910
 
                {
911
 
                  switch (tok[ i])
912
 
                    {
913
 
                      case '(':
914
 
                        break;
915
 
                      case ')':
916
 
                        break;
917
 
                      case ',':
918
 
                        if (j == 0)
919
 
                          {
920
 
                            perms = 0;
921
 
                            j = 1;
922
 
                          }
923
 
                        else
924
 
                          {
925
 
                            perms <<= 3;
926
 
                          }
927
 
                        break;
928
 
                    case 'R':
929
 
                      perms |= 4;
930
 
                      break;
931
 
                    case 'W':
932
 
                      perms |= 2;
933
 
                      break;
934
 
                    case 'E':
935
 
                      perms |= 1;
936
 
                      break;
937
 
                    case 'D':
938
 
                      perms |= 2;
939
 
                      break;
940
 
                    }
941
 
                }
942
 
              cur.perms = perms;
943
 
              DEBUGP (("Prot.  perms = %0o.\n", cur.perms));
944
 
            }
945
 
          else
946
 
            {
947
 
              /* Nondescript.  Probably size(s), probably in blocks.
 
887
          if ((strlen (tok) < 12) && (strchr( tok, '-') != NULL))
 
888
            {
 
889
              /* Date. */
 
890
              DEBUGP (("Date.\n"));
 
891
              strcpy( date_str, tok);
 
892
              strcat( date_str, " ");
 
893
            }
 
894
          else if ((strlen (tok) < 12) && (strchr( tok, ':') != NULL))
 
895
            {
 
896
              /* Time. */
 
897
              DEBUGP (("Time. "));
 
898
              strncat( date_str,
 
899
                       tok,
 
900
                       (sizeof( date_str)- strlen (date_str) - 1));
 
901
              DEBUGP (("Date time: >%s<\n", date_str));
 
902
            }
 
903
          else if (strchr ( tok, '[') != NULL)
 
904
            {
 
905
              /* Owner.  (Ignore.) */
 
906
              DEBUGP (("Owner.\n"));
 
907
            }
 
908
          else if (strchr (tok, '(') != NULL)
 
909
            {
 
910
              /* Protections (permissions). */
 
911
              perms = 0;
 
912
              j = 0;
 
913
              for (i = 0; i < strlen( tok); i++)
 
914
                {
 
915
                  switch (tok[ i])
 
916
                    {
 
917
                    case '(':
 
918
                      break;
 
919
                    case ')':
 
920
                      break;
 
921
                    case ',':
 
922
                      if (j == 0)
 
923
                        {
 
924
                          perms = 0;
 
925
                          j = 1;
 
926
                        }
 
927
                      else
 
928
                        {
 
929
                          perms <<= 3;
 
930
                        }
 
931
                      break;
 
932
                    case 'R':
 
933
                      perms |= 4;
 
934
                      break;
 
935
                    case 'W':
 
936
                      perms |= 2;
 
937
                      break;
 
938
                    case 'E':
 
939
                      perms |= 1;
 
940
                      break;
 
941
                    case 'D':
 
942
                      perms |= 2;
 
943
                      break;
 
944
                    }
 
945
                }
 
946
              cur.perms = perms;
 
947
              DEBUGP (("Prot.  perms = %0o.\n", cur.perms));
 
948
            }
 
949
          else
 
950
            {
 
951
              /* Nondescript.  Probably size(s), probably in blocks.
948
952
                 Could be "No privilege ..." message.  (Ignore.)
949
953
              */
950
 
              DEBUGP (("Ignored (size?).\n"));
951
 
            }
 
954
              DEBUGP (("Ignored (size?).\n"));
 
955
            }
952
956
 
953
 
          tok = strtok (NULL, " ");
954
 
        }
 
957
          tok = strtok (NULL, " ");
 
958
        }
955
959
 
956
960
      /* Tokens exhausted.  Interpret the data, and fill in the
957
961
         structure.
967
971
      /* Convert struct tm local time to time_t local time. */
968
972
      timenow = mktime (timestruct);
969
973
      /* Offset local time according to environment variable (seconds). */
970
 
      if ((tok = getenv( "WGET_TIMEZONE_DIFFERENTIAL")) != NULL)
 
974
      if ((tok = getenv ( "WGET_TIMEZONE_DIFFERENTIAL")) != NULL)
971
975
        {
972
 
          dt = atoi( tok);
 
976
          dt = atoi (tok);
973
977
          DEBUGP (("Time differential = %d.\n", dt));
974
978
        }
975
979
      else
976
 
        {
977
 
          dt = 0;
978
 
        }
 
980
        dt = 0;
979
981
 
980
982
      if (dt >= 0)
981
 
        {
982
 
          timenow += dt;
983
 
        }
 
983
        timenow += dt;
984
984
      else
985
 
        {
986
 
          timenow -= (-dt);
987
 
        }
 
985
        timenow -= (-dt);
 
986
 
988
987
      cur.tstamp = timenow; /* Store the time-stamp. */
989
 
      DEBUGP(("Timestamp: %ld\n", cur.tstamp));
 
988
      DEBUGP (("Timestamp: %ld\n", cur.tstamp));
 
989
      cur.ptype = TT_HOUR_MIN;
990
990
 
991
991
      /* Add the data for this item to the linked list, */
992
992
      if (!dir)
1134
1134
 
1135
1135
          fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
1136
1136
                  ptm->tm_mday);
1137
 
          if (ptm->tm_hour)
 
1137
          if (f->ptype == TT_HOUR_MIN)
1138
1138
            fprintf (fp, "%02d:%02d  ", ptm->tm_hour, ptm->tm_min);
1139
1139
          else
1140
1140
            fprintf (fp, "       ");