Amos Shapira schrieb:
On 19/07/07, *Dirk* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    But after I have introduced some more enhancements to the converter, I
    have another idea:

    One could write a "PreConversion Hook" in the sence of
    MergeParentdata,
    RemoveTemporaryCheckIns, MergeUnpinPinData or BuildComments and check
    for these types of activities. With some tricks one could figure
    out the
    best timstamp and modify the conversion database. With these types of
    hooks you can do almost anything to the database, that can be changed
    without an in depth knowledge about the logical structure.


So what you area suggesting (and I'm not familiar with the code beyond a cursory look a few weeks ago) is to leave the input file alone but fake the timestamp via a hook so the rest of vss2svn will think it is the better one?

If you can do some development work in perl, I would go for option 2. If you are not familar with PERL, but familiar with C++ I would go for modifying ssphys. If you are familar with a hexeditor, have a look at the 010 Editor [1], you can modify the timestamps yourself. I have attached a template file for the 010 Editor that can decode the phyiscal files. This template file is from my first experiments with decoding the archive.

I'm sorry, that I have very little time currently to do some programming. Otherwise I would help with option 2. Until then I can only help you with information.

Dirk

[1] http://www.sweetscape.com/010editor/
<cid:part1.02090807.00080101@nogga.de>
//--------------------------------------
//--- 010 Editor v1.3.2 Binary Template
//
// File:
// Author:
// Purpose: decodes general SourceSafe files like (aaaaaaaa)
//--------------------------------------

typedef struct {
  long size;  
  char type[2];
  short checksum;
} HEADER;

enum <ushort> ACTION { 
  Labeled = 0,
  Created_Project = 1,          //??
  Added_Project = 2,
  Added_File = 3,
  Destroyed_Project = 4,
  Destroyed_File = 5,
  Deleted_Project = 6,
  Deleted_File = 7,
  Recovered_Project = 8,
  Recovered_File = 9,
  Renamed_Project = 10,
  Renamed_File = 11,
  // missing action 12,
  // missing action 13
  Shared_File = 14,     
  // missing action 15
  Created_File = 16,
  Checked_in = 17,
  // missing action 18
  RollBack = 19,
  ArchiveVersions_File = 20,
  ArchiveVersions_Project = 21,
  Archive_File = 22,
  Archive_Project = 23,
  Restore_File = 24,
  Restore_Project = 25,

  // missing known actions: branches, archives, restores
};

typedef struct {
  short flags;          // 00 = item, 01 == project
  char name[34];        // short name
  long nsmap;           // offset into the names.dat
} SSNAME;
  
typedef struct {
  long previous;        // previous ProjectEntry
  ACTION action;
  short version;
  time_t date;
  char user[32];

  char label[32];
  // offset zum nächsten EL record
  long offsetToNextRecordOrComment2;

  // After a rollback activity:
  // this was a offset to the next FD record, 
  // and another time it was the files size 
  // Dies schient immer der comment zu sein. Im Falle eines Labels ist es der 
LabelComment
  long offsetToComment1;                // MC record

  // Länge der comments
  short lengthComment2;
  short lengthComment1;
} PROJENTRY;

typedef struct {
  SSNAME name;
  char physical[9];
} DUMMY_ACTION;

typedef struct {
  int empty;
} CREATED_PROJECT_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} DELETED_PROJECT_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} RECOVERED_PROJECT_ACTION;

typedef struct {
  SSNAME newName;
  SSNAME oldName;
  char physical[9];
} RENAMED_PROJECT_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} RECOVERED_FILE_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} DELETED_FILE_ACTION;

typedef struct {
  SSNAME name;
  short padding;
  char physical[9];
} DESTROYED_FILE_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} ADDED_FILE_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} CREATED_FILE_ACTION;

typedef struct {
  SSNAME newName;
  SSNAME oldName;
  char physical[9];
} RENAMED_FILE_ACTION;

typedef struct {
  char srcPathSpec[260];
  SSNAME name;
  short padding1;
  short pinnedToVersion;
  short padding2;  // Pinned?
  char physical[10];
} SHARED_FILE_ACTION;

typedef struct {
  SSNAME name;
  char physical[9];
} ADDED_PROJECT_ACTION;

typedef struct {
  char padding[8];
  char checkInSpec[260];
} CHECKED_IN_ACTION;

typedef struct {
  SSNAME name;
  char physical[10];
  char parent[10];
} ROLLBACK_ACTION;

typedef struct {
  SSNAME  name;
  char    physical[10];
  char unknown2[12];
  short version;
  char targetFile[252];
} ARCHIVE_VERSIONS_ACTION;

typedef struct {
  SSNAME name;
  char physical[10];
  short dummy;
  char filename[264];
} ARCHIVE_ACTION;

typedef struct {
  SSNAME name;
  char physical[10];
  short dummy;
  char filename[264];
} RESTORE_ACTION;

typedef struct {
  short type; // 1 Project, 2 File

  short numberOfRecords;

  // This is the last name that was given to the item
  SSNAME name;  
  short firstVersion;
  char fileExt[2]; // .A or .B

  // offsets for records
  int i1;  // first EL Header
  int i2;  // last EL oder FD HEader
  int i3;  // size of the file
} DH;

typedef struct {
  char dummy4[20];
  
  // 0x00 initial
  // 0x02 == binary
  // 0x04 == store only latest revision
  // 0x41 == checked out
  // 0x20 == shared
  short flag; 
  char shareSrcSpec[10];

  unsigned long offsetBFRecord;
  unsigned long offsetPFRecord; // offset to the last PF record in der Liste
  short numberOfBranches;
  short numberOfReferences;     // Reference count for the item

  unsigned long offsetCFRecord1; // file checked out, ptr to CF record
  unsigned long offsetCFRecord2; // file not checked out, ptr to CF record
  int unknown1; // changes after checkin

  char dummy5[8];

  // diese scheinen immer Paare zu bilden, nach einem Checkin ändert sich
  // der d11, d21 
  // d12 == d22 == d32
  short d11;
  short d12;
  short d21;
  short d22;
  short d31;
  short d32;

  char dummy6[4];

  // dito wie dxx, jedoch zum ersten mal nach einem Checkin
  short e11;
  short e12;
  short e21;
  short e22;
  short e31;
  short e32;

  char dummy7[200];

  short numberOfItems;        // including projects
  short numberOfProjects;     // number of subprojects
} DH_ITEM;

typedef struct {
  char dummy4[20];
  
  char parentSpec[34];       // of last checkout
  char dummy7[226];

  char parentPhys[9];
  char dummy8[3];

  short numberOfItems;        // including projects
  short numberOfProjects;
} DH_PROJECT;


typedef struct {
  char user[32];
  char padding[4];
  // zusammen 260?
  char CheckOutFolder[256];
  char padding2[4];
  char computer[32];
  // zusammen 260
//  char parentSpec[80];
//  char fileSpec2[60];
//  char padding3[120];
  char parentSpec[260];

  char comment[13];
  char padding4[51];

  // initial alles 0
  // Check Out: flag1=01, flag2=40, flag3=00
  // Check In : flag1=00, flag2=00, flag3=10
  char flag1;
  char padding5;
  char flag2;
  char padding6[8];
  char flag3;
  int numberOfVersions;
} CF;

typedef struct {
  long previous;
  char parent[10];
  short padding;
} PF;

typedef struct {
  int dummy;
} MC;

typedef struct {
  int command; // 01 copy, 00 replace, 02
  long start;
  long end;
} FD;

typedef struct {
  long previous;
  char branch[10];
  short dummy2;
} BF;

char fileHeader[0x34];
local long currentPos = 0;
local long len;
local long count = 0;

while (!FEof())
{
   HEADER h;
   currentPos = FTell ();
   
   if (h.type == "DH") 
   {
     DH dh;
     if (dh.type == 1)
       DH_PROJECT project;
     else
       DH_ITEM item;
   }
   else if (h.type == "CF") 
   {
     CF cf;
   }
   else if (h.type == "PF") 
   {
     // Zeigt auf einen weiteren Share (ProjectFolder?)
     PF pf;
   }
   else if (h.type == "FD") 
   {
     // forward delta?? oder file delta
     FD fd;
   }
   else if (h.type == "BF") 
   {
     // forward delta?? oder file delta
     BF bf;
   }
   else if (h.type == "MC") 
   {
     // einfacher String mit Länge h.size
     len = h.size;
     // char string[len];
   }
   else if (h.type == "EL") 
   {
     PROJENTRY r;
     if (r.action == Created_File)
     { CREATED_FILE_ACTION a; }
     else if (r.action == Added_File)
     { ADDED_FILE_ACTION a; }
     else if (r.action == Created_Project)
     { CREATED_PROJECT_ACTION a; }
     else if (r.action == Added_Project)
     { ADDED_PROJECT_ACTION a; }
     else if (r.action == Deleted_Project)
     { DELETED_PROJECT_ACTION a; }
     else if (r.action == Recovered_Project)
     { RECOVERED_PROJECT_ACTION a; }
     else if (r.action == Renamed_Project)
     { RENAMED_PROJECT_ACTION a; }
     else if (r.action == Checked_in)
     { CHECKED_IN_ACTION d; }
     else if (r.action == Shared_File)
     { SHARED_FILE_ACTION a; }
     else if (r.action == Recovered_File)
     { RECOVERED_FILE_ACTION a; }
     else if (r.action == Deleted_File)
     { DELETED_FILE_ACTION a; }
     else if (r.action == Destroyed_File)
     { DESTROYED_FILE_ACTION a; }
     else if (r.action == Renamed_File)
     { RENAMED_FILE_ACTION a; }
     else if (r.action == RollBack)
     { ROLLBACK_ACTION a; }
     else if (r.action == ArchiveVersions_File)
     { ARCHIVE_VERSIONS_ACTION a; }
     else if (r.action == ArchiveVersions_Project)
     { ARCHIVE_VERSIONS_ACTION a; }
     else if (r.action == Archive_File)
     { ARCHIVE_ACTION a; }
     else if (r.action == Archive_Project)
     { ARCHIVE_ACTION a; }
     else if (r.action == Restore_Project)
     { RESTORE_ACTION a; }
     else if (r.action == Restore_File)
     { RESTORE_ACTION a; }
     else // if (r.action == Checked_in)
     { DUMMY_ACTION r2; }
   }
   else if (h.type == "DH") 
   {
   }
   else
        Warning ("unknown header %s", h.type);

   FSeek (currentPos + h.size);
}

Warning ("%d EL Header", count);
_______________________________________________
vss2svn-users mailing list
Project homepage:
http://www.pumacode.org/projects/vss2svn/
Subscribe/Unsubscribe/Admin:
http://lists.pumacode.org/mailman/listinfo/vss2svn-users-lists.pumacode.org
Mailing list web interface (with searchable archives):
http://dir.gmane.org/gmane.comp.version-control.subversion.vss2svn.user

Reply via email to