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 ---