diff -c par2cmdline-0.4-gcc4/commandline.cpp par2cmdline-0.4/commandline.cpp
*** par2cmdline-0.4-gcc4/commandline.cpp	2004-04-15 15:44:40.000000000 +0100
--- par2cmdline-0.4/commandline.cpp	2012-11-02 12:51:03.969722207 +0000
***************
*** 58,63 ****
--- 58,64 ----
  : operation(opNone)
  , version(verUnknown)
  , noiselevel(nlUnknown)
+ , listtype(ltBoth)
  , blockcount(0)
  , blocksize(0)
  , firstblock(0)
***************
*** 84,89 ****
--- 85,91 ----
      "  par2 c(reate) [options] <par2 file> [files] : Create PAR2 files\n"
      "  par2 v(erify) [options] <par2 file> [files] : Verify files using PAR2 file\n"
      "  par2 r(epair) [options] <par2 file> [files] : Repair files using PAR2 files\n"
+     "  par2 l(ist)   [options] <par2 file> [files] : List files using PAR2 files\n"
      "\n"
      "You may also leave out the \"c\", \"v\", and \"r\" commands by using \"parcreate\",\n"
      "\"par2verify\", or \"par2repair\" instead.\n"
***************
*** 101,106 ****
--- 103,110 ----
      "  -m<n>  : Memory (in MB) to use\n"
      "  -v [-v]: Be more verbose\n"
      "  -q [-q]: Be more quiet (-q -q gives silence)\n"
+     "  -e     : List only recovery files\n"
+     "  -o     : List only source files\n"
      "  --     : Treat all remaining CommandLine as filenames\n"
      "\n"
      "If you wish to create par2 files for a single source file, you may leave\n"
***************
*** 163,168 ****
--- 167,180 ----
        if (argv[0][1] == 0 || 0 == stricmp(argv[0], "repair"))
          operation = opRepair;
        break;
+     case 'l':
+       if (argv[0][1] == 0 || 0 == stricmp(argv[0], "list"))
+       {
+         operation = opList;
+         noiselevel = nlSilent;
+         listtype = ltBoth;
+       }
+       break;
      }
      if (operation == opNone)
      {
***************
*** 519,524 ****
--- 531,548 ----
            }
            break;
  
+         case 'e': // List only recovery files
+           {
+             listtype = ltRecovery;
+           }
+           break;
+ 
+         case 'o': // List only source files
+           {
+             listtype = ltSource;
+           }
+           break;
+ 
          case '-':
            {
              argc--;
diff -c par2cmdline-0.4-gcc4/commandline.h par2cmdline-0.4/commandline.h
*** par2cmdline-0.4-gcc4/commandline.h	2004-04-15 11:31:37.000000000 +0100
--- par2cmdline-0.4/commandline.h	2012-11-02 12:50:43.821716166 +0000
***************
*** 41,47 ****
      opNone = 0,
      opCreate,        // Create new PAR2 recovery volumes
      opVerify,        // Verify but don't repair damaged data files
!     opRepair         // Verify and if possible repair damaged data files
    } Operation;
  
    typedef enum
--- 41,48 ----
      opNone = 0,
      opCreate,        // Create new PAR2 recovery volumes
      opVerify,        // Verify but don't repair damaged data files
!     opRepair,        // Verify and if possible repair damaged data files
!     opList           // List all PAR2 and target files
    } Operation;
  
    typedef enum
***************
*** 69,74 ****
--- 70,82 ----
      nlDebug         // Extra debugging information
    } NoiseLevel;
  
+   typedef enum
+   {
+     ltRecovery = (1 << 0), // List only recovery files
+     ltSource   = (1 << 1), // List only source files
+     ltBoth     = (ltRecovery | ltSource)  // List both recovery & source files
+   } ListType;
+ 
    // Any extra files listed on the command line
    class ExtraFile
    {
***************
*** 103,108 ****
--- 111,117 ----
    u64                    GetLargestSourceSize(void) const  {return largestsourcesize;}
    u64                    GetTotalSourceSize(void) const    {return totalsourcesize;}
    CommandLine::NoiseLevel GetNoiseLevel(void) const        {return noiselevel;}
+   CommandLine::ListType  GetListType(void) const           {return listtype;};
  
    string                              GetParFilename(void) const {return parfilename;}
    const list<CommandLine::ExtraFile>& GetExtraFiles(void) const  {return extrafiles;}
***************
*** 113,118 ****
--- 122,129 ----
  
    NoiseLevel noiselevel;       // How much display output should there be.
  
+   ListType listtype;           // Which file types to list
+ 
    u32 blockcount;              // How many blocks the source files should 
                                 // be virtually split into.
  
Only in par2cmdline-0.4: config.h.in
diff -c par2cmdline-0.4-gcc4/diskfile.cpp par2cmdline-0.4/diskfile.cpp
*** par2cmdline-0.4-gcc4/diskfile.cpp	2004-04-12 12:25:37.000000000 +0100
--- par2cmdline-0.4/diskfile.cpp	2012-11-02 12:50:43.821716166 +0000
***************
*** 995,997 ****
--- 995,1013 ----
  
    return (f != diskfilemap.end()) ?  f->second : 0;
  }
+ 
+ void DiskFileMap::List(void)
+ {
+   map<string, DiskFile*>::iterator fi = diskfilemap.begin();
+   while (fi != diskfilemap.end())
+   {
+     DiskFile *diskfile = (*fi).second;
+     string path;
+     string name;
+     DiskFile::SplitFilename(diskfile->FileName(), path, name);
+ 
+     cout << name << endl;
+ 
+     ++fi;
+   }
+ }
diff -c par2cmdline-0.4-gcc4/diskfile.h par2cmdline-0.4/diskfile.h
*** par2cmdline-0.4-gcc4/diskfile.h	2003-05-26 19:01:14.000000000 +0100
--- par2cmdline-0.4/diskfile.h	2012-11-02 12:50:43.821716166 +0000
***************
*** 117,122 ****
--- 117,123 ----
    bool Insert(DiskFile *diskfile);
    void Remove(DiskFile *diskfile);
    DiskFile* Find(string filename) const;
+   void List();
  
  protected:
    map<string, DiskFile*>    diskfilemap;             // Map from filename to DiskFile
diff -c par2cmdline-0.4-gcc4/par2cmdline.cpp par2cmdline-0.4/par2cmdline.cpp
*** par2cmdline-0.4-gcc4/par2cmdline.cpp	2004-04-15 12:49:23.000000000 +0100
--- par2cmdline-0.4/par2cmdline.cpp	2012-11-02 12:50:43.821716166 +0000
***************
*** 124,129 ****
--- 124,153 ----
          }
        }
        break;
+     case CommandLine::opList:
+       {
+         // Repair damaged files
+         switch (commandline->GetVersion())
+         {
+         case CommandLine::verPar1:
+           {
+             Par1Repairer *repairer = new Par1Repairer;
+             result = repairer->Process(*commandline, true);
+             delete repairer;
+           }
+           break;
+         case CommandLine::verPar2:
+           {
+             Par2Repairer *repairer = new Par2Repairer;
+             result = repairer->List(*commandline);
+             delete repairer;
+           }
+           break;
+         case CommandLine::opNone:
+           break;
+         }
+       }
+       break;
      case CommandLine::opNone:
        break;
      }
diff -c par2cmdline-0.4-gcc4/par2repairer.cpp par2cmdline-0.4/par2repairer.cpp
*** par2cmdline-0.4-gcc4/par2repairer.cpp	2004-04-15 14:42:48.000000000 +0100
--- par2cmdline-0.4/par2repairer.cpp	2012-11-02 12:50:43.841702395 +0000
***************
*** 255,260 ****
--- 255,324 ----
    return eSuccess;
  }
  
+ Result Par2Repairer::List(const CommandLine &commandline)
+ {
+   // What noiselevel are we using
+   noiselevel = commandline.GetNoiseLevel();
+ 
+   // Get filesnames from the command line
+   string par2filename = commandline.GetParFilename();
+   DiskFile *par2DiskFile = new DiskFile();
+   par2DiskFile->Open(par2filename, 0);
+   par2DiskFile->Close();
+   diskFileMap.Insert(par2DiskFile);
+ 
+   const list<CommandLine::ExtraFile> &extrafiles = commandline.GetExtraFiles();
+ 
+   // Determine the searchpath from the location of the main PAR2 file
+   string name;
+   DiskFile::SplitFilename(par2filename, searchpath, name);
+ 
+   // Load packets from the main PAR2 file
+   if (!LoadPacketsFromFile(searchpath + name))
+     return eLogicError;
+ 
+   // Load packets from other PAR2 files with names based on the original PAR2 file
+   if (!LoadPacketsFromOtherFiles(par2filename))
+     return eLogicError;
+ 
+   // Load packets from any other PAR2 files whose names are given on the command line
+   if (!LoadPacketsFromExtraFiles(extrafiles))
+     return eLogicError;
+ 
+   // Check that the packets are consistent and discard any that are not
+   if (!CheckPacketConsistency())
+     return eInsufficientCriticalData;
+ 
+   // List all files in the recovery data map
+   if (commandline.GetListType() & CommandLine::ltRecovery)
+   {
+     diskFileMap.List();
+   }
+ 
+   // Use the information in the main packet to get the source files
+   // into the correct order and determine their filenames
+   if (!CreateSourceFileList())
+     return eLogicError;
+ 
+   // List all source (target) files found
+   if (commandline.GetListType() & CommandLine::ltSource)
+   {
+     vector<Par2RepairerSourceFile*>::iterator sf = sourcefiles.begin();
+     while (sf != sourcefiles.end())
+     {
+       Par2RepairerSourceFile *sourcefile = *sf;
+       if (sourcefile)
+       {
+         cout << sourcefile->GetDescriptionPacket()->FileName() << endl;
+       }
+       // iterate to next source file
+       ++sf; 
+     }
+   }
+ 
+   return eSuccess;
+ }
+ 
  // Load the packets from the specified file
  bool Par2Repairer::LoadPacketsFromFile(string filename)
  {
diff -c par2cmdline-0.4-gcc4/par2repairer.h par2cmdline-0.4/par2repairer.h
*** par2cmdline-0.4-gcc4/par2repairer.h	2004-04-15 12:23:02.000000000 +0100
--- par2cmdline-0.4/par2repairer.h	2012-11-02 12:50:43.841702395 +0000
***************
*** 27,32 ****
--- 27,33 ----
    ~Par2Repairer(void);
  
    Result Process(const CommandLine &commandline, bool dorepair);
+   Result List(const CommandLine &commandline);
  
  protected:
    // Steps in verifying and repairing files:
