summaryrefslogtreecommitdiff
blob: e1ed67fa45d9c6866cf06a3194ee2908cdf81a63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/******************************* LICENCE **************************************
* Any code in this file may be redistributed or modified under the terms of
* the GNU General Public Licence as published by the Free Software 
* Foundation; version 2 of the licence.
****************************** END LICENCE ***********************************/

/******************************************************************************
* Author:
* Andrew Smith, http://littlesvr.ca/misc/contactandrew.php
*
* Contributors:
* 
******************************************************************************/

/********************************* PURPOSE ************************************
* bk.h
* This header file is the public interface to bkisofs.
******************************** END PURPOSE *********************************/

#ifndef bk_h
#define bk_h

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <limits.h>
#include <sys/timeb.h>
#include <stdio.h>

#include "bkError.h"

#ifdef WINDOWS_BUILD
    /* on windows i can't get an off_t to be 64 bits */
    typedef long long bk_off_t;
    #define bk_lseek _lseeki64
    typedef struct _stati64 BkStatStruct;
#else
    typedef off_t bk_off_t;
    #define bk_lseek lseek
    typedef struct stat BkStatStruct;
#endif

/* can be |ed */
#define FNTYPE_9660 1
#define FNTYPE_ROCKRIDGE 2
#define FNTYPE_JOLIET 4

/* many library functions rely on this being at least 256 */
#define NCHARS_FILE_ID_MAX_STORE 256

/* maximum length of the target of a symbolic link
* !! this is used for both the number of characters in the path and the number
* of bytes in the SL record, that should probably be fixed */
#define NCHARS_SYMLINK_TARGET_MAX 251

/* maximum number of bytes to read from a file for comparing it quickly
* with others (is it likely to be a hard link or not) */
#define MAX_NBYTES_HARDLINK_HEAD 32

/* options for VolInfo.bootMediaType */
#define BOOT_MEDIA_NONE 0
#define BOOT_MEDIA_NO_EMULATION 1
#define BOOT_MEDIA_1_2_FLOPPY 2 /* 1228800 byte floppy disk image */
#define BOOT_MEDIA_1_44_FLOPPY 3 /* 1474560 byte floppy disk image */
#define BOOT_MEDIA_2_88_FLOPPY 4 /* 2949120 byte floppy disk image */
#define BOOT_MEDIA_HARD_DISK 5

#define READ_WRITE_BUFFER_SIZE 102400

/* warning message string lengths in VolInfo */
#define BK_WARNING_MAX_LEN 512

#define IS_DIR(posix)      ((posix & 0770000) == 0040000)
#define IS_REG_FILE(posix) ((posix & 0770000) == 0100000)
#define IS_SYMLINK(posix)  ((posix & 0770000) == 0120000)

#define BK_BASE_PTR(item) ((BkFileBase*)(item))
#define BK_DIR_PTR(item) ((BkDir*)(item))
#define BK_FILE_PTR(item) ((BkFile*)(item))
#define BK_SYMLINK_PTR(item) ((BkSymLink*)(item))

/*******************************************************************************
* BkFileBase
* Linked list node.
* All files, directories, links need this. */
typedef struct BkFileBase
{
    char original9660name[15]; /* 8.3 + ";1" max */
    char name[NCHARS_FILE_ID_MAX_STORE]; /* '\0' terminated */
    unsigned posixFileMode; /* file type and permissions */
    
    struct BkFileBase* next;
    
} BkFileBase;

/*******************************************************************************
* BkDir
* Linked list node.
* Information about a directory and it's contents. */
typedef struct BkDir
{
    BkFileBase base; /* intended to be accessed using a cast */
    
    BkFileBase* children; /* child directories, files, etc. */
    
} BkDir;

/*******************************************************************************
* BkHardLink
* Linked list node.
* Information about a hard link (where to find a certain file).
* This is for internal use but is defined here because BkFile references it.
* You don't need to use this structure, please ignore it. */
typedef struct BkHardLink
{
    bool onImage;
    bk_off_t position; /* if on image */
    char* pathAndName; /* if on filesystem, full path + filename
                       * is to be freed whenever the BkHardLink is freed */
    unsigned size; /* size of the file being pointed to */
    int headSize;
    unsigned char head[MAX_NBYTES_HARDLINK_HEAD];
    bool alreadyCounted; /* for estimateIsoSize() */
    
    unsigned extentNumberWrittenTo; /* only set once one file is written */
    
    struct BkHardLink* next;
    
} BkHardLink;

/*******************************************************************************
* BkFile
* Linked list node.
* Information about a file, whether on the image or on the filesystem. */
typedef struct BkFile
{
    BkFileBase base; /* intended to be accessed using a cast */
    
    unsigned size; /* in bytes, don't need bk_off_t because it's stored 
                   * in a 32bit unsigned int on the iso */
    BkHardLink* location; /* basically a copy of the following variables */
    bool onImage;
    bk_off_t position; /* if on image, in bytes */
    char* pathAndName; /* if on filesystem, full path + filename
                       * is to be freed whenever the File is freed */
    
} BkFile;

/*******************************************************************************
* BkSymLink
* Linked list node.
* Information about a symbolic link. */
typedef struct BkSymLink
{
    BkFileBase base; /* intended to be accessed using a cast */
    
    char target[NCHARS_SYMLINK_TARGET_MAX];
    
} BkSymLink;

/*******************************************************************************
* VolInfo
* Information about a volume (one image).
* Strings are '\0' terminated. */
typedef struct VolInfo
{
    /* private bk use  */
    unsigned filenameTypes;
    bk_off_t pRootDrOffset; /* primary (9660 and maybe rockridge) */
    bk_off_t sRootDrOffset; /* secondary (joliet), 0 if does not exist */
    bk_off_t bootRecordSectorNumberOffset;
    int imageForReading;
    ino_t imageForReadingInode; /* to know which file was open for reading
                                * (filename is not reliable) */
    const BkFile* bootRecordOnImage; /* if visible, pointer to the file in the 
                                     *  directory tree */
    char warningMessage[BK_WARNING_MAX_LEN];
    bool rootRead; /* did i read the root record inside volume descriptor? */
    bool stopOperation; /* cancel current opertion */
    int imageForWriting;
    void(*progressFunction)(struct VolInfo*);
    void(*writeProgressFunction)(struct VolInfo*, double);
    struct timeb lastTimeCalledProgress;
    bk_off_t estimatedIsoSize;
    BkHardLink* fileLocations; /* list of where to find regular files */
    char readWriteBuffer[READ_WRITE_BUFFER_SIZE];
    char readWriteBuffer2[READ_WRITE_BUFFER_SIZE];
    
    /* public use, read only */
    time_t creationTime;
    BkDir dirTree;
    unsigned char bootMediaType;
    unsigned bootRecordSize;       /* in bytes */
    bool bootRecordIsOnImage;      /* unused if visible (flag below) */
    bk_off_t bootRecordOffset;     /* if on image */
    char* bootRecordPathAndName;   /* if on filesystem */
    bool bootRecordIsVisible;      /* whether boot record is a visible file 
                                   *  on the image */
    bool scanForDuplicateFiles;    /* whether to check every file for uniqueness
                                   * to decide is it a hard link or not */
    
    /* public use, read/write */
    char volId[33];
    char publisher[129];
    char dataPreparer[129];
    unsigned posixFileDefaults;    /* for extracting */
    unsigned posixDirDefaults;     /* for extracting or creating on iso */
    bool(*warningCbk)(const char*);
    bool followSymLinks;           /* whether to stat the link itself rather 
                                   *  than the file it's pointing to */
    
} VolInfo;

/* public bkisofs functions */

/* adding */
int bk_add_boot_record(VolInfo* volInfo, const char* srcPathAndName, 
                       int bootMediaType);
int bk_add(VolInfo* volInfo, const char* srcPathAndName, 
           const char* destPathStr, void(*progressFunction)(VolInfo*));
int bk_add_as(VolInfo* volInfo, const char* srcPathAndName, 
              const char* destPathStr, const char* nameToUse, 
              void(*progressFunction)(VolInfo*));
int bk_create_dir(VolInfo* volInfo, const char* destPathStr, 
                  const char* newDirName);

/* deleting */
void bk_delete_boot_record(VolInfo* volInfo);
int bk_delete(VolInfo* volInfo, const char* pathAndName);

/* extracting */
int bk_extract_boot_record(VolInfo* volInfo, const char* destPathAndName,
                           unsigned destFilePerms);
int bk_extract(VolInfo* volInfo, const char* srcPathAndName, 
               const char* destDir, bool keepPermissions, 
               void(*progressFunction)(VolInfo*));
int bk_extract_as(VolInfo* volInfo, const char* srcPathAndName, 
                  const char* destDir, const char* nameToUse,
                  bool keepPermissions, void(*progressFunction)(VolInfo*));

/* getters */
bk_off_t bk_estimate_iso_size(const VolInfo* volInfo, int filenameTypes);
time_t bk_get_creation_time(const VolInfo* volInfo);
int bk_get_dir_from_string(const VolInfo* volInfo, const char* pathStr, 
                           BkDir** dirFoundPtr);
int bk_get_permissions(VolInfo* volInfo, const char* pathAndName, 
                       mode_t* permissions);
const char* bk_get_publisher(const VolInfo* volInfo);
const char* bk_get_volume_name(const VolInfo* volInfo);
const char* bk_get_error_string(int errorId);

/* setters */
void bk_cancel_operation(VolInfo* volInfo);
void bk_destroy_vol_info(VolInfo* volInfo);
int bk_init_vol_info(VolInfo* volInfo, bool scanForDuplicateFiles);
int bk_rename(VolInfo* volInfo, const char* srcPathAndName, 
              const char* newName);
int bk_set_boot_file(VolInfo* volInfo, const char* srcPathAndName);
void bk_set_follow_symlinks(VolInfo* volInfo, bool doFollow);
int bk_set_permissions(VolInfo* volInfo, const char* pathAndName, 
                       mode_t permissions);
int bk_set_publisher(VolInfo* volInfo, const char* publisher);
int bk_set_vol_name(VolInfo* volInfo, const char* volName);

/* reading */
int bk_open_image(VolInfo* volInfo, const char* filename);
int bk_read_dir_tree(VolInfo* volInfo, int filenameType, 
                     bool keepPosixPermissions, 
                     void(*progressFunction)(VolInfo*));
int bk_read_vol_info(VolInfo* volInfo);

/* writing */
int bk_write_image(const char* newImagePathAndName, VolInfo* volInfo, 
                   time_t creationTime, int filenameTypes, 
                   void(*progressFunction)(VolInfo*, double));

#ifdef __cplusplus
}
#endif

#endif