1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 16 /** 17 * Archive to parse cpio data in the newc and crc formats. Generate a cpio archive like that by e.g. 18 * find . | cpio -o -H newc > archive.cpio 19 */ 20 21 #pragma once 22 23 #include <stdio.h> 24 #include <stdint.h> 25 #include <stdbool.h> 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #define CPIO_MODE_FILETYPE_MASK 0xF000 32 #define CPIO_MODE_FILETYPE_SOCKET 0xC000 33 #define CPIO_MODE_FILETYPE_SYMLINK 0xA000 34 #define CPIO_MODE_FILETYPE_REGULAR 0x8000 35 #define CPIO_MODE_FILETYPE_BLOCKDEV 0x6000 36 #define CPIO_MODE_FILETYPE_DIR 0x4000 37 #define CPIO_MODE_FILETYPE_CHARDEV 0x2000 38 #define CPIO_MODE_FILETYPE_FIFO 0x1000 39 #define CPIO_MODE_SUID 0x0800 40 #define CPIO_MODE_SGID 0x0400 41 #define CPIO_MODE_STICKY 0x0200 42 43 typedef struct { 44 size_t filesize; 45 char *name; 46 uint32_t mode; 47 uint32_t check; 48 } cpio_file_t; 49 50 typedef enum { 51 CPIO_RET_MORE = 0, 52 CPIO_RET_DONE, 53 CPIO_RET_ERR 54 } cpio_ret_t; 55 56 typedef struct cpio_handle_data_t cpio_handle_data_t; 57 typedef cpio_handle_data_t *cpio_handle_t; 58 59 typedef enum { 60 CPIO_RSN_FILE_ALL = 0, 61 CPIO_RSN_FILE_INITIAL, 62 CPIO_RSN_FILE_MORE, 63 CPIO_RSN_FILE_END 64 } cpio_callback_reason_t; 65 66 67 /** 68 * Callback for cpio file data. 69 * 70 * This callback will be called by the library to indicate data for a file is available. 71 * 72 * For files in the cpio archive that fit entirely in the internal buffer, or when no internal 73 * buffer is available, are entirely contained in the buffer fed to cpio_feed(), this callback 74 * is only called once, with reason=CPIO_RNS_FILE_ALL. fileinfo will contain the information 75 * for that specific file (name, size, ...), buff_offset will be 0, buff_len is the file 76 * size and buff contains all the information for the file. 77 * 78 * For files that do not fit in the buffer, this callback will be called multiple times. 79 * The initial time with reason=CPIO_RSN_FILE_INITIAL, when more data is available with 80 * CPIO_RSN_FILE_MORE and finally with CPIO_RSN_FILE_END. For these calls, fileinfo 81 * will again contain file information. buff will be the information contained in the 82 * file at offset buff_offset, and the lenght of this buffer will be in buff_len. 83 * 84 * The library guarantees to feed all file data to the callback consequitively, so 85 * within the same file, the buff_offset from a call will always be (buff_offset+buff_len) 86 * from the call before that. If cpio_start is 87 * 88 * The library also guarantees every file in the cpio archive will either generate a single 89 * callback call with CPIO_RSN_ALL, or multiple with in sequence CPIO_RSN_FILE_INITIAL, 0 or 90 * more CPIO_RSN_FILE_MORE and finally a CPIO_RSN_FILE_END. 91 * 92 * When a non-zero buffer size is passed to cpio_start, the library guarantees that all callback 93 * calls with a reason of CPIO_RSN_FILE_INITIAL and CPIO_RSN_FILE_MORE will have a buffer 94 * filled with exactly this amount of bytes. 95 * 96 */ 97 typedef void (*cpio_callback_t)(cpio_callback_reason_t reason, cpio_file_t *fileinfo, size_t buff_offset, size_t buff_len, char *buff, void *arg); 98 99 100 /** 101 * @brief Initialize a cpio handle. 102 * 103 * Call this to start parsing a cpio archive. You can set the callback that handles the 104 * files/data here. 105 * 106 * @param callback The callback that will handle the data of the files inside the cpio archive 107 * 108 * @param cbarg User-supplied argument. The callback will be called with this as an argument. 109 * 110 * @param buflen Length of internal buffer used. 111 * If this is zero, the callback will be called with data that lives in the data buffer 112 * supplied to the cpio library by whomever called cpio_feed(). Because this library has 113 * no power over that buffer, the callback can be passed as little as 1 and as many as 114 * INT_MAX bytes at a time. 115 * If this is non-zero, the library will allocate an internal buffer of this size. All 116 * cpio_feed()-calls will be rebuffered, and the callback is guaranteed to only be called 117 * with this many bytes in the buffer, given there's enough data in the file to fill it. 118 * 119 * @param memchunk Chunk of memory to allocate everything (handle, I/O buffer, filename buffer) in. Minimum size 120 * (estimate) is 160+buflen+sizeof(largest filename/path). 121 * @param memchunklen Size of the mem chunk 122 * 123 * @return 124 * - Success: A pointer to a cpio handle 125 * - Error: NULL 126 * 127 */ 128 cpio_handle_t cpio_start(cpio_callback_t callback, void *cbarg, size_t buflen, void *memchunk, int memchunklen); 129 130 /** 131 * @brief Feed data from a cpio archive into the library 132 * 133 * This routine is used to feed consecutive data of the cpio archive into the library. While processing, 134 * the library can call the callback function one or more times if needed. 135 * 136 * @param cpio Handle obtained by calling cpio_start() 137 * 138 * @param buffer Pointer to buffer containing cpio archive data 139 * 140 * @param len Length of the buffer, in bytes 141 * 142 * @return 143 * - CPIO_RET_MORE: CPIO archive isn't done yet, please feed more data. 144 * - CPIO_RET_DONE: CPUI archive is finished. 145 * - CPIO_RET_ERR: Invalid CPIO archive data; decoding aborted. 146 * 147 */ 148 cpio_ret_t cpio_feed(cpio_handle_t cpio, char *buffer, int len); 149 150 /** 151 * @brief Indicate there is no more cpio data to be fed into the archive 152 * 153 * This call is to be called when the source data is exhausted. Normally, the library can find the end of the 154 * cpio archive by looking for the end marker, 155 * 156 * @param timer_conf Pointer of LEDC timer configure struct 157 * 158 * 159 * @return 160 * - CPIO_RET_DONE on success 161 * - CPIO_RET_ERR when cpio archive is invalid 162 * 163 */ 164 cpio_ret_t cpio_done(cpio_handle_t cpio); 165 166 167 /** 168 * @brief Free the memory allocated for a cpio handle. 169 * 170 * @param cpio Handle obtained by calling cpio_start() 171 * 172 * @return 173 * - CPIO_RET_DONE on success 174 * 175 */ 176 cpio_ret_t cpio_destroy(cpio_handle_t cpio); 177 178 #ifdef __cplusplus 179 } 180 #endif 181