archive_read_support_format_raw.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*-
  2. * Copyright (c) 2003-2009 Tim Kientzle
  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
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "archive_platform.h"
  26. __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107 2009-12-28 03:25:33Z kientzle $");
  27. #ifdef HAVE_ERRNO_H
  28. #include <errno.h>
  29. #endif
  30. #include <stdio.h>
  31. #ifdef HAVE_STDLIB_H
  32. #include <stdlib.h>
  33. #endif
  34. #include "archive.h"
  35. #include "archive_entry.h"
  36. #include "archive_private.h"
  37. #include "archive_read_private.h"
  38. struct raw_info {
  39. int64_t offset; /* Current position in the file. */
  40. int64_t unconsumed;
  41. int end_of_file;
  42. };
  43. static int archive_read_format_raw_bid(struct archive_read *, int);
  44. static int archive_read_format_raw_cleanup(struct archive_read *);
  45. static int archive_read_format_raw_read_data(struct archive_read *,
  46. const void **, size_t *, int64_t *);
  47. static int archive_read_format_raw_read_data_skip(struct archive_read *);
  48. static int archive_read_format_raw_read_header(struct archive_read *,
  49. struct archive_entry *);
  50. int
  51. archive_read_support_format_raw(struct archive *_a)
  52. {
  53. struct raw_info *info;
  54. struct archive_read *a = (struct archive_read *)_a;
  55. int r;
  56. archive_check_magic(_a, ARCHIVE_READ_MAGIC,
  57. ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
  58. info = (struct raw_info *)calloc(1, sizeof(*info));
  59. if (info == NULL) {
  60. archive_set_error(&a->archive, ENOMEM,
  61. "Can't allocate raw_info data");
  62. return (ARCHIVE_FATAL);
  63. }
  64. r = __archive_read_register_format(a,
  65. info,
  66. "raw",
  67. archive_read_format_raw_bid,
  68. NULL,
  69. archive_read_format_raw_read_header,
  70. archive_read_format_raw_read_data,
  71. archive_read_format_raw_read_data_skip,
  72. NULL,
  73. archive_read_format_raw_cleanup,
  74. NULL,
  75. NULL);
  76. if (r != ARCHIVE_OK)
  77. free(info);
  78. return (r);
  79. }
  80. /*
  81. * Bid 1 if this is a non-empty file. Anyone who can really support
  82. * this should outbid us, so it should generally be safe to use "raw"
  83. * in conjunction with other formats. But, this could really confuse
  84. * folks if there are bid errors or minor file damage, so we don't
  85. * include "raw" as part of support_format_all().
  86. */
  87. static int
  88. archive_read_format_raw_bid(struct archive_read *a, int best_bid)
  89. {
  90. if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL)
  91. return (1);
  92. return (-1);
  93. }
  94. /*
  95. * Mock up a fake header.
  96. */
  97. static int
  98. archive_read_format_raw_read_header(struct archive_read *a,
  99. struct archive_entry *entry)
  100. {
  101. struct raw_info *info;
  102. info = (struct raw_info *)(a->format->data);
  103. if (info->end_of_file)
  104. return (ARCHIVE_EOF);
  105. a->archive.archive_format = ARCHIVE_FORMAT_RAW;
  106. a->archive.archive_format_name = "raw";
  107. archive_entry_set_pathname(entry, "data");
  108. archive_entry_set_filetype(entry, AE_IFREG);
  109. archive_entry_set_perm(entry, 0644);
  110. /* I'm deliberately leaving most fields unset here. */
  111. return (ARCHIVE_OK);
  112. }
  113. static int
  114. archive_read_format_raw_read_data(struct archive_read *a,
  115. const void **buff, size_t *size, int64_t *offset)
  116. {
  117. struct raw_info *info;
  118. ssize_t avail;
  119. info = (struct raw_info *)(a->format->data);
  120. /* Consume the bytes we read last time. */
  121. if (info->unconsumed) {
  122. __archive_read_consume(a, info->unconsumed);
  123. info->unconsumed = 0;
  124. }
  125. if (info->end_of_file)
  126. return (ARCHIVE_EOF);
  127. /* Get whatever bytes are immediately available. */
  128. *buff = __archive_read_ahead(a, 1, &avail);
  129. if (avail > 0) {
  130. /* Return the bytes we just read */
  131. *size = avail;
  132. *offset = info->offset;
  133. info->offset += *size;
  134. info->unconsumed = avail;
  135. return (ARCHIVE_OK);
  136. } else if (0 == avail) {
  137. /* Record and return end-of-file. */
  138. info->end_of_file = 1;
  139. *size = 0;
  140. *offset = info->offset;
  141. return (ARCHIVE_EOF);
  142. } else {
  143. /* Record and return an error. */
  144. *size = 0;
  145. *offset = info->offset;
  146. return ((int)avail);
  147. }
  148. }
  149. static int
  150. archive_read_format_raw_read_data_skip(struct archive_read *a)
  151. {
  152. struct raw_info *info = (struct raw_info *)(a->format->data);
  153. /* Consume the bytes we read last time. */
  154. if (info->unconsumed) {
  155. __archive_read_consume(a, info->unconsumed);
  156. info->unconsumed = 0;
  157. }
  158. info->end_of_file = 1;
  159. return (ARCHIVE_OK);
  160. }
  161. static int
  162. archive_read_format_raw_cleanup(struct archive_read *a)
  163. {
  164. struct raw_info *info;
  165. info = (struct raw_info *)(a->format->data);
  166. free(info);
  167. a->format->data = NULL;
  168. return (ARCHIVE_OK);
  169. }