Fossil SCM

Support symlinks in tarballs.

dmitry 2011-08-24 20:01 symlinks
Commit 72e3bbd0710eb85dba76da3c5ab958cc57cb13c5
1 file changed +20 -4
+20 -4
--- src/tar.c
+++ src/tar.c
@@ -280,11 +280,12 @@
280280
const char *zName, /* Name of the object */
281281
int nName, /* Number of characters in zName */
282282
int iMode, /* Mode. 0644 or 0755 */
283283
unsigned int mTime, /* File modification time */
284284
int iSize, /* Size of the object in bytes */
285
- char cType /* Type of object. '0'==file. '5'==directory */
285
+ char cType /* Type of object:
286
+ '0'==file. '2'==symlink. '5'==directory */
286287
){
287288
/* set mode and modification time */
288289
sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode);
289290
sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime);
290291
@@ -359,20 +360,35 @@
359360
** Add a single file to the growing tarball.
360361
*/
361362
static void tar_add_file(
362363
const char *zName, /* Name of the file. nul-terminated */
363364
Blob *pContent, /* Content of the file */
364
- int isExe, /* True for executable files */
365
+ int mPerm, /* 1: executable file, 2: symlink */
365366
unsigned int mTime /* Last modification time of the file */
366367
){
367368
int nName = strlen(zName);
368369
int n = blob_size(pContent);
369370
int lastPage;
371
+ char cType = '0';
370372
371373
/* length check moved to tar_split_path */
372374
tar_add_directory_of(zName, nName, mTime);
373
- tar_add_header(zName, nName, isExe ? 0755 : 0644, mTime, n, '0');
375
+
376
+ /*
377
+ * If we have a symlink, write its destination path (which is stored in
378
+ * pContent) into header, and set content length to 0 to avoid storing path
379
+ * as file content in the next step. Since 'linkname' header is limited to
380
+ * 100 bytes (-1 byte for terminating zero), if path is greater than that,
381
+ * store symlink as a plain-text file. (Not sure how TAR handles long links.)
382
+ */
383
+ if( mPerm == 2 && n <= 100 ){
384
+ sqlite3_snprintf(100, (char*)&tball.aHdr[157], "%s", blob_str(pContent));
385
+ cType = '2';
386
+ n = 0;
387
+ }
388
+
389
+ tar_add_header(zName, nName, (mPerm > 0) ? 0755 : 0644, mTime, n, cType);
374390
if( n ){
375391
gzip_step(blob_buffer(pContent), n);
376392
lastPage = n % 512;
377393
if( lastPage!=0 ){
378394
gzip_step(tball.zSpaces, 512 - lastPage);
@@ -415,11 +431,11 @@
415431
tar_begin();
416432
for(i=3; i<g.argc; i++){
417433
blob_zero(&file);
418434
blob_read_from_file(&file, g.argv[i]);
419435
tar_add_file(g.argv[i], &file,
420
- file_isexe(g.argv[i]), file_mtime(g.argv[i]));
436
+ file_perm(g.argv[i]), file_mtime(g.argv[i]));
421437
blob_reset(&file);
422438
}
423439
tar_finish(&zip);
424440
blob_write_to_file(&zip, g.argv[2]);
425441
}
426442
--- src/tar.c
+++ src/tar.c
@@ -280,11 +280,12 @@
280 const char *zName, /* Name of the object */
281 int nName, /* Number of characters in zName */
282 int iMode, /* Mode. 0644 or 0755 */
283 unsigned int mTime, /* File modification time */
284 int iSize, /* Size of the object in bytes */
285 char cType /* Type of object. '0'==file. '5'==directory */
 
286 ){
287 /* set mode and modification time */
288 sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode);
289 sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime);
290
@@ -359,20 +360,35 @@
359 ** Add a single file to the growing tarball.
360 */
361 static void tar_add_file(
362 const char *zName, /* Name of the file. nul-terminated */
363 Blob *pContent, /* Content of the file */
364 int isExe, /* True for executable files */
365 unsigned int mTime /* Last modification time of the file */
366 ){
367 int nName = strlen(zName);
368 int n = blob_size(pContent);
369 int lastPage;
 
370
371 /* length check moved to tar_split_path */
372 tar_add_directory_of(zName, nName, mTime);
373 tar_add_header(zName, nName, isExe ? 0755 : 0644, mTime, n, '0');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374 if( n ){
375 gzip_step(blob_buffer(pContent), n);
376 lastPage = n % 512;
377 if( lastPage!=0 ){
378 gzip_step(tball.zSpaces, 512 - lastPage);
@@ -415,11 +431,11 @@
415 tar_begin();
416 for(i=3; i<g.argc; i++){
417 blob_zero(&file);
418 blob_read_from_file(&file, g.argv[i]);
419 tar_add_file(g.argv[i], &file,
420 file_isexe(g.argv[i]), file_mtime(g.argv[i]));
421 blob_reset(&file);
422 }
423 tar_finish(&zip);
424 blob_write_to_file(&zip, g.argv[2]);
425 }
426
--- src/tar.c
+++ src/tar.c
@@ -280,11 +280,12 @@
280 const char *zName, /* Name of the object */
281 int nName, /* Number of characters in zName */
282 int iMode, /* Mode. 0644 or 0755 */
283 unsigned int mTime, /* File modification time */
284 int iSize, /* Size of the object in bytes */
285 char cType /* Type of object:
286 '0'==file. '2'==symlink. '5'==directory */
287 ){
288 /* set mode and modification time */
289 sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode);
290 sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime);
291
@@ -359,20 +360,35 @@
360 ** Add a single file to the growing tarball.
361 */
362 static void tar_add_file(
363 const char *zName, /* Name of the file. nul-terminated */
364 Blob *pContent, /* Content of the file */
365 int mPerm, /* 1: executable file, 2: symlink */
366 unsigned int mTime /* Last modification time of the file */
367 ){
368 int nName = strlen(zName);
369 int n = blob_size(pContent);
370 int lastPage;
371 char cType = '0';
372
373 /* length check moved to tar_split_path */
374 tar_add_directory_of(zName, nName, mTime);
375
376 /*
377 * If we have a symlink, write its destination path (which is stored in
378 * pContent) into header, and set content length to 0 to avoid storing path
379 * as file content in the next step. Since 'linkname' header is limited to
380 * 100 bytes (-1 byte for terminating zero), if path is greater than that,
381 * store symlink as a plain-text file. (Not sure how TAR handles long links.)
382 */
383 if( mPerm == 2 && n <= 100 ){
384 sqlite3_snprintf(100, (char*)&tball.aHdr[157], "%s", blob_str(pContent));
385 cType = '2';
386 n = 0;
387 }
388
389 tar_add_header(zName, nName, (mPerm > 0) ? 0755 : 0644, mTime, n, cType);
390 if( n ){
391 gzip_step(blob_buffer(pContent), n);
392 lastPage = n % 512;
393 if( lastPage!=0 ){
394 gzip_step(tball.zSpaces, 512 - lastPage);
@@ -415,11 +431,11 @@
431 tar_begin();
432 for(i=3; i<g.argc; i++){
433 blob_zero(&file);
434 blob_read_from_file(&file, g.argv[i]);
435 tar_add_file(g.argv[i], &file,
436 file_perm(g.argv[i]), file_mtime(g.argv[i]));
437 blob_reset(&file);
438 }
439 tar_finish(&zip);
440 blob_write_to_file(&zip, g.argv[2]);
441 }
442

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button