archive_read_support_format_raw.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. /* Let the filter fill out any fields it might have. */
  112. return __archive_read_header(a, entry);
  113. }
  114. static int
  115. archive_read_format_raw_read_data(struct archive_read *a,
  116. const void **buff, size_t *size, int64_t *offset)
  117. {
  118. struct raw_info *info;
  119. ssize_t avail;
  120. info = (struct raw_info *)(a->format->data);
  121. /* Consume the bytes we read last time. */
  122. if (info->unconsumed) {
  123. __archive_read_consume(a, info->unconsumed);
  124. info->unconsumed = 0;
  125. }
  126. if (info->end_of_file)
  127. return (ARCHIVE_EOF);
  128. /* Get whatever bytes are immediately available. */
  129. *buff = __archive_read_ahead(a, 1, &avail);
  130. if (avail > 0) {
  131. /* Return the bytes we just read */
  132. *size = avail;
  133. *offset = info->offset;
  134. info->offset += *size;
  135. info->unconsumed = avail;
  136. return (ARCHIVE_OK);
  137. } else if (0 == avail) {
  138. /* Record and return end-of-file. */
  139. info->end_of_file = 1;
  140. *size = 0;
  141. *offset = info->offset;
  142. return (ARCHIVE_EOF);
  143. } else {
  144. /* Record and return an error. */
  145. *size = 0;
  146. *offset = info->offset;
  147. return ((int)avail);
  148. }
  149. }
  150. static int
  151. archive_read_format_raw_read_data_skip(struct archive_read *a)
  152. {
  153. struct raw_info *info = (struct raw_info *)(a->format->data);
  154. /* Consume the bytes we read last time. */
  155. if (info->unconsumed) {
  156. __archive_read_consume(a, info->unconsumed);
  157. info->unconsumed = 0;
  158. }
  159. info->end_of_file = 1;
  160. return (ARCHIVE_OK);
  161. }
  162. static int
  163. archive_read_format_raw_cleanup(struct archive_read *a)
  164. {
  165. struct raw_info *info;
  166. info = (struct raw_info *)(a->format->data);
  167. free(info);
  168. a->format->data = NULL;
  169. return (ARCHIVE_OK);
  170. }