write.c (cb0dad38e4faf38d13b6b7406659555ff40ea83f) | write.c (0c099281a3c52b1effd3bfb3775d62e2d8f64cf4) |
---|---|
1/*- 2 * Copyright (c) 2007 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 46 unchanged lines hidden (view full) --- 55static void add_to_ar_str_table(struct bsdar *bsdar, const char *name); 56static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name); 57static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, 58 const char *name, time_t mtime); 59static void create_symtab_entry(struct bsdar *bsdar, void *maddr, 60 size_t size); 61static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, 62 struct ar_obj *pos); | 1/*- 2 * Copyright (c) 2007 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 46 unchanged lines hidden (view full) --- 55static void add_to_ar_str_table(struct bsdar *bsdar, const char *name); 56static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name); 57static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, 58 const char *name, time_t mtime); 59static void create_symtab_entry(struct bsdar *bsdar, void *maddr, 60 size_t size); 61static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, 62 struct ar_obj *pos); |
63static void read_objs(struct bsdar *bsdar, const char *archive, 64 int checkargv); |
|
63static void write_archive(struct bsdar *bsdar, char mode); 64static void write_cleanup(struct bsdar *bsdar); 65static void write_data(struct bsdar *bsdar, struct archive *a, 66 const void *buf, size_t s); 67static void write_objs(struct bsdar *bsdar); 68 69void 70ar_mode_d(struct bsdar *bsdar) --- 25 unchanged lines hidden (view full) --- 96 97void 98ar_mode_s(struct bsdar *bsdar) 99{ 100 101 write_archive(bsdar, 's'); 102} 103 | 65static void write_archive(struct bsdar *bsdar, char mode); 66static void write_cleanup(struct bsdar *bsdar); 67static void write_data(struct bsdar *bsdar, struct archive *a, 68 const void *buf, size_t s); 69static void write_objs(struct bsdar *bsdar); 70 71void 72ar_mode_d(struct bsdar *bsdar) --- 25 unchanged lines hidden (view full) --- 98 99void 100ar_mode_s(struct bsdar *bsdar) 101{ 102 103 write_archive(bsdar, 's'); 104} 105 |
106void 107ar_mode_A(struct bsdar *bsdar) 108{ 109 110 write_archive(bsdar, 'A'); 111} 112 |
|
104/* 105 * Create object from file, return created obj upon success, or NULL 106 * when an error occurs or the member is not newer than existing 107 * one while -u is specifed. 108 */ 109static struct ar_obj * 110create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime) 111{ --- 101 unchanged lines hidden (view full) --- 213 } 214 215tail: 216 TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); 217 218} 219 220/* | 113/* 114 * Create object from file, return created obj upon success, or NULL 115 * when an error occurs or the member is not newer than existing 116 * one while -u is specifed. 117 */ 118static struct ar_obj * 119create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime) 120{ --- 101 unchanged lines hidden (view full) --- 222 } 223 224tail: 225 TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); 226 227} 228 229/* |
221 * Determine the constitution of resulting archive. | 230 * Read objects from archive into v_obj list. Note that checkargv is 231 * set when read_objs is used to read objects from the target of 232 * ADDLIB command (ar script mode), in this case argv array possibly 233 * specifies the members ADDLIB want. |
222 */ 223static void | 234 */ 235static void |
224write_archive(struct bsdar *bsdar, char mode) | 236read_objs(struct bsdar *bsdar, const char *archive, int checkargv) |
225{ 226 struct archive *a; 227 struct archive_entry *entry; | 237{ 238 struct archive *a; 239 struct archive_entry *entry; |
228 struct ar_obj *nobj, *obj, *obj_temp, *pos; 229 struct stat sb; | 240 struct ar_obj *obj; |
230 const char *name; 231 const char *bname; 232 char *buff; 233 char **av; 234 size_t size; | 241 const char *name; 242 const char *bname; 243 char *buff; 244 char **av; 245 size_t size; |
235 int i, r; | 246 int i, r, find; |
236 | 247 |
237 TAILQ_INIT(&bsdar->v_obj); 238 nobj = NULL; 239 pos = NULL; 240 memset(&sb, 0, sizeof(sb)); 241 242 /* By default, no compression is assumed. */ 243 bsdar->compression = ARCHIVE_COMPRESSION_NONE; 244 245 /* 246 * Test if the specified archive exists, to figure out 247 * whether we are creating one here. 248 */ 249 if (stat(bsdar->filename, &sb) != 0) { 250 if (errno != ENOENT) { 251 bsdar_warnc(bsdar, 0, "stat %s failed", 252 bsdar->filename); 253 return; 254 } 255 256 /* We do not create archive in mode 'd', 'm' and 's'. */ 257 if (mode != 'r' && mode != 'q') { 258 bsdar_warnc(bsdar, 0, "%s: no such file", 259 bsdar->filename); 260 return; 261 } 262 263 /* Issue a warning if -c is not specified when creating. */ 264 if (!(bsdar->options & AR_C)) 265 bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename); 266 goto new_archive; 267 } 268 269 /* 270 * First read members from existing archive. 271 */ | |
272 if ((a = archive_read_new()) == NULL) 273 bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed"); 274 archive_read_support_compression_all(a); 275 archive_read_support_format_ar(a); | 248 if ((a = archive_read_new()) == NULL) 249 bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed"); 250 archive_read_support_compression_all(a); 251 archive_read_support_format_ar(a); |
276 AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ)); | 252 AC(archive_read_open_filename(a, archive, DEF_BLKSZ)); |
277 for (;;) { 278 r = archive_read_next_header(a, &entry); 279 if (r == ARCHIVE_FATAL) 280 bsdar_errc(bsdar, EX_DATAERR, 0, "%s", 281 archive_error_string(a)); 282 if (r == ARCHIVE_EOF) 283 break; 284 if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) --- 13 unchanged lines hidden (view full) --- 298 name = archive_entry_pathname(entry); 299 300 /* 301 * skip pseudo members. 302 */ 303 if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0) 304 continue; 305 | 253 for (;;) { 254 r = archive_read_next_header(a, &entry); 255 if (r == ARCHIVE_FATAL) 256 bsdar_errc(bsdar, EX_DATAERR, 0, "%s", 257 archive_error_string(a)); 258 if (r == ARCHIVE_EOF) 259 break; 260 if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) --- 13 unchanged lines hidden (view full) --- 274 name = archive_entry_pathname(entry); 275 276 /* 277 * skip pseudo members. 278 */ 279 if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0) 280 continue; 281 |
282 /* 283 * If checkargv is set, only read those members specified 284 * in argv. 285 */ 286 if (checkargv && bsdar->argc > 0) { 287 find = 0; 288 for(i = 0; i < bsdar->argc; i++) { 289 av = &bsdar->argv[i]; 290 if (*av == NULL) 291 continue; 292 if ((bname = basename(*av)) == NULL) 293 bsdar_errc(bsdar, EX_SOFTWARE, errno, 294 "basename failed"); 295 if (strcmp(bname, name) != 0) 296 continue; 297 298 *av = NULL; 299 find = 1; 300 break; 301 } 302 if (!find) 303 continue; 304 } 305 |
|
306 size = archive_entry_size(entry); 307 308 if (size > 0) { 309 if ((buff = malloc(size)) == NULL) 310 bsdar_errc(bsdar, EX_SOFTWARE, errno, 311 "malloc failed"); 312 if (archive_read_data(a, buff, size) != (ssize_t)size) { 313 bsdar_warnc(bsdar, 0, "%s", --- 22 unchanged lines hidden (view full) --- 336 * Objects from archive have obj->fd set to -1, 337 * for the ease of cleaning up. 338 */ 339 obj->fd = -1; 340 TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); 341 } 342 AC(archive_read_close(a)); 343 AC(archive_read_finish(a)); | 306 size = archive_entry_size(entry); 307 308 if (size > 0) { 309 if ((buff = malloc(size)) == NULL) 310 bsdar_errc(bsdar, EX_SOFTWARE, errno, 311 "malloc failed"); 312 if (archive_read_data(a, buff, size) != (ssize_t)size) { 313 bsdar_warnc(bsdar, 0, "%s", --- 22 unchanged lines hidden (view full) --- 336 * Objects from archive have obj->fd set to -1, 337 * for the ease of cleaning up. 338 */ 339 obj->fd = -1; 340 TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); 341 } 342 AC(archive_read_close(a)); 343 AC(archive_read_finish(a)); |
344} |
|
344 | 345 |
346/* 347 * Determine the constitution of resulting archive. 348 */ 349static void 350write_archive(struct bsdar *bsdar, char mode) 351{ 352 struct ar_obj *nobj, *obj, *obj_temp, *pos; 353 struct stat sb; 354 const char *bname; 355 char **av; 356 int i; 357 358 TAILQ_INIT(&bsdar->v_obj); 359 nobj = NULL; 360 pos = NULL; 361 memset(&sb, 0, sizeof(sb)); 362 363 /* By default, no compression is assumed. */ 364 bsdar->compression = ARCHIVE_COMPRESSION_NONE; 365 |
|
345 /* | 366 /* |
367 * Test if the specified archive exists, to figure out 368 * whether we are creating one here. 369 */ 370 if (stat(bsdar->filename, &sb) != 0) { 371 if (errno != ENOENT) { 372 bsdar_warnc(bsdar, 0, "stat %s failed", 373 bsdar->filename); 374 return; 375 } 376 377 /* We do not create archive in mode 'd', 'm' and 's'. */ 378 if (mode != 'r' && mode != 'q') { 379 bsdar_warnc(bsdar, 0, "%s: no such file", 380 bsdar->filename); 381 return; 382 } 383 384 /* Issue a warning if -c is not specified when creating. */ 385 if (!(bsdar->options & AR_C)) 386 bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename); 387 goto new_archive; 388 } 389 390 /* 391 * First read members from existing archive. 392 */ 393 read_objs(bsdar, bsdar->filename, 0); 394 395 /* |
|
346 * For mode 's', no member will be moved, deleted or replaced. 347 */ 348 if (mode == 's') 349 goto write_objs; 350 351 /* 352 * For mode 'q', we don't need to adjust existing members either. 353 * Also, -a, -b and -i are ignored in this mode. New members are 354 * always inserted at tail. 355 */ 356 if (mode == 'q') 357 goto new_archive; 358 359 /* | 396 * For mode 's', no member will be moved, deleted or replaced. 397 */ 398 if (mode == 's') 399 goto write_objs; 400 401 /* 402 * For mode 'q', we don't need to adjust existing members either. 403 * Also, -a, -b and -i are ignored in this mode. New members are 404 * always inserted at tail. 405 */ 406 if (mode == 'q') 407 goto new_archive; 408 409 /* |
410 * Mode 'A' adds the contents of another archive to the tail of 411 * current archive. Note that mode 'A' is a special mode for the 412 * ADDLIB command of the ar script mode. Currently there is no 413 * access to this function from the ar command line mode. 414 */ 415 if (mode == 'A') { 416 /* 417 * Read objects from the target archive of ADDLIB command. 418 * If there are members spcified in argv, read those members 419 * only, otherwise the entire archive will be read. 420 */ 421 read_objs(bsdar, bsdar->addlib, 1); 422 goto write_objs; 423 } 424 425 /* |
|
360 * Try to find the position member specified by user. 361 */ 362 if (bsdar->options & AR_A || bsdar->options & AR_B) { 363 TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { 364 if (strcmp(obj->name, bsdar->posarg) == 0) { 365 pos = obj; 366 break; 367 } --- 446 unchanged lines hidden --- | 426 * Try to find the position member specified by user. 427 */ 428 if (bsdar->options & AR_A || bsdar->options & AR_B) { 429 TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { 430 if (strcmp(obj->name, bsdar->posarg) == 0) { 431 pos = obj; 432 break; 433 } --- 446 unchanged lines hidden --- |