1 //  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
2 //  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
3 //
4 //  Copyright (c) 2003 Peter Brian Clements
5 //
6 //  par2cmdline is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 2 of the License, or
9 //  (at your option) any later version.
10 //
11 //  par2cmdline is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19 
20 #include "par2cmdline.h"
21 
22 #ifdef _MSC_VER
23 #ifdef _DEBUG
24 #undef THIS_FILE
25 static char THIS_FILE[]=__FILE__;
26 #define new DEBUG_NEW
27 #endif
28 #endif
29 
30 // Construct the creator packet.
31 
32 // The only external information required to complete construction is
33 // the set_id_hash (which is normally computed from information in the
34 // main packet).
35 
Create(const MD5Hash & setid)36 bool CreatorPacket::Create(const MD5Hash &setid)
37 {
38   string creator = "Created by " PACKAGE " version " VERSION ".";
39 
40   // Allocate a packet just large enough for creator name
41   CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket(sizeof(*packet) + (~3 & (3+(u32)creator.size())));
42 
43   // Fill in the details the we know
44   packet->header.magic = packet_magic;
45   packet->header.length = packetlength;
46   //packet->header.hash;  // Compute shortly
47   packet->header.setid = setid;
48   packet->header.type = creatorpacket_type;
49 
50   // Copy the creator description into the packet
51   memcpy(packet->client, creator.c_str(), creator.size());
52 
53   // Compute the packet hash
54   MD5Context packetcontext;
55   packetcontext.Update(&packet->header.setid, packetlength - offsetof(PACKET_HEADER, setid));
56   packetcontext.Final(packet->header.hash);
57 
58   return true;
59 }
60 
61 // Load the packet from disk.
62 
Load(DiskFile * diskfile,u64 offset,PACKET_HEADER & header)63 bool CreatorPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header)
64 {
65   // Is the packet long enough
66   if (header.length <= sizeof(CREATORPACKET))
67   {
68     return false;
69   }
70 
71   // Is the packet too large (what is the longest reasonable creator description)
72   if (header.length - sizeof(CREATORPACKET) > 100000)
73   {
74     return false;
75   }
76 
77   // Allocate the packet (with a little extra so we will have NULLs after the description)
78   CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket((size_t)header.length, 4);
79   packet->header = header;
80 
81   // Load the rest of the packet from disk
82   return diskfile->Read(offset + sizeof(PACKET_HEADER),
83                         packet->client,
84                         (size_t)packet->header.length - sizeof(PACKET_HEADER));
85 }
86