Added microtar library

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2025-08-06 05:09:07 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2025-08-06 05:09:07 +0200
Commit 2914af44b185e860bb04d3bb062a4cd928b0bab7 (patch)
-rw-r--r-- archive/microtar-0.1.0.tar.gz bin 0 B -> 4.7 KB
-rw-r--r-- vendor/microtar-0.1.0/LICENSE 19
-rw-r--r-- vendor/microtar-0.1.0/README.md 99
-rw-r--r-- vendor/microtar-0.1.0/src/microtar.c 376
-rw-r--r-- vendor/microtar-0.1.0/src/microtar.h 82
5 files changed, 576 insertions, 0 deletions
diff --git a/archive/microtar-0.1.0.tar.gz b/archive/microtar-0.1.0.tar.gz
diff --git a/vendor/microtar-0.1.0/LICENSE b/vendor/microtar-0.1.0/LICENSE
  
1
Copyright (c) 2017 rxi
  
2
  
  
3
Permission is hereby granted, free of charge, to any person obtaining a copy of
  
4
this software and associated documentation files (the "Software"), to deal in
  
5
the Software without restriction, including without limitation the rights to
  
6
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  
7
of the Software, and to permit persons to whom the Software is furnished to do
  
8
so, subject to the following conditions:
  
9
  
  
10
The above copyright notice and this permission notice shall be included in all
  
11
copies or substantial portions of the Software.
  
12
  
  
13
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  
14
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  
15
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  
16
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  
17
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  
18
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  
19
SOFTWARE.
diff --git a/vendor/microtar-0.1.0/README.md b/vendor/microtar-0.1.0/README.md
  
1
# microtar
  
2
A lightweight tar library written in ANSI C
  
3
  
  
4
  
  
5
## Basic Usage
  
6
The library consists of `microtar.c` and `microtar.h`. These two files can be
  
7
dropped into an existing project and compiled along with it.
  
8
  
  
9
  
  
10
#### Reading
  
11
```c
  
12
mtar_t tar;
  
13
mtar_header_t h;
  
14
char *p;
  
15
  
  
16
/* Open archive for reading */
  
17
mtar_open(&tar, "test.tar", "r");
  
18
  
  
19
/* Print all file names and sizes */
  
20
while ( (mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD ) {
  
21
  printf("%s (%d bytes)\n", h.name, h.size);
  
22
  mtar_next(&tar);
  
23
}
  
24
  
  
25
/* Load and print contents of file "test.txt" */
  
26
mtar_find(&tar, "test.txt", &h);
  
27
p = calloc(1, h.size + 1);
  
28
mtar_read_data(&tar, p, h.size);
  
29
printf("%s", p);
  
30
free(p);
  
31
  
  
32
/* Close archive */
  
33
mtar_close(&tar);
  
34
```
  
35
  
  
36
#### Writing
  
37
```c
  
38
mtar_t tar;
  
39
const char *str1 = "Hello world";
  
40
const char *str2 = "Goodbye world";
  
41
  
  
42
/* Open archive for writing */
  
43
mtar_open(&tar, "test.tar", "w");
  
44
  
  
45
/* Write strings to files `test1.txt` and `test2.txt` */
  
46
mtar_write_file_header(&tar, "test1.txt", strlen(str1));
  
47
mtar_write_data(&tar, str1, strlen(str1));
  
48
mtar_write_file_header(&tar, "test2.txt", strlen(str2));
  
49
mtar_write_data(&tar, str2, strlen(str2));
  
50
  
  
51
/* Finalize -- this needs to be the last thing done before closing */
  
52
mtar_finalize(&tar);
  
53
  
  
54
/* Close archive */
  
55
mtar_close(&tar);
  
56
```
  
57
  
  
58
  
  
59
## Error handling
  
60
All functions which return an `int` will return `MTAR_ESUCCESS` if the operation
  
61
is successful. If an error occurs an error value less-than-zero will be
  
62
returned; this value can be passed to the function `mtar_strerror()` to get its
  
63
corresponding error string.
  
64
  
  
65
  
  
66
## Wrapping a stream
  
67
If you want to read or write from something other than a file, the `mtar_t`
  
68
struct can be manually initialized with your own callback functions and a
  
69
`stream` pointer.
  
70
  
  
71
All callback functions are passed a pointer to the `mtar_t` struct as their
  
72
first argument. They should return `MTAR_ESUCCESS` if the operation succeeds
  
73
without an error, or an integer below zero if an error occurs.
  
74
  
  
75
After the `stream` field has been set, all required callbacks have been set and
  
76
all unused fields have been zeroset the `mtar_t` struct can be safely used with
  
77
the microtar functions. `mtar_open` *should not* be called if the `mtar_t`
  
78
struct was initialized manually.
  
79
  
  
80
#### Reading
  
81
The following callbacks should be set for reading an archive from a stream:
  
82
  
  
83
Name    | Arguments                                | Description
  
84
--------|------------------------------------------|---------------------------
  
85
`read`  | `mtar_t *tar, void *data, unsigned size` | Read data from the stream
  
86
`seek`  | `mtar_t *tar, unsigned pos`              | Set the position indicator
  
87
`close` | `mtar_t *tar`                            | Close the stream
  
88
  
  
89
#### Writing
  
90
The following callbacks should be set for writing an archive to a stream:
  
91
  
  
92
Name    | Arguments                                      | Description
  
93
--------|------------------------------------------------|---------------------
  
94
`write` | `mtar_t *tar, const void *data, unsigned size` | Write data to the stream
  
95
  
  
96
  
  
97
## License
  
98
This library is free software; you can redistribute it and/or modify it under
  
99
the terms of the MIT license. See [LICENSE](LICENSE) for details.
diff --git a/vendor/microtar-0.1.0/src/microtar.c b/vendor/microtar-0.1.0/src/microtar.c
  
1
/*
  
2
 * Copyright (c) 2017 rxi
  
3
 *
  
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
  
5
 * of this software and associated documentation files (the "Software"), to
  
6
 * deal in the Software without restriction, including without limitation the
  
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  
8
 * sell copies of the Software, and to permit persons to whom the Software is
  
9
 * furnished to do so, subject to the following conditions:
  
10
 *
  
11
 * The above copyright notice and this permission notice shall be included in
  
12
 * all copies or substantial portions of the Software.
  
13
 *
  
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  
20
 * IN THE SOFTWARE.
  
21
 */
  
22
  
  
23
#include <stdio.h>
  
24
#include <stdlib.h>
  
25
#include <stddef.h>
  
26
#include <string.h>
  
27
  
  
28
#include "microtar.h"
  
29
  
  
30
typedef struct {
  
31
  char name[100];
  
32
  char mode[8];
  
33
  char owner[8];
  
34
  char group[8];
  
35
  char size[12];
  
36
  char mtime[12];
  
37
  char checksum[8];
  
38
  char type;
  
39
  char linkname[100];
  
40
  char _padding[255];
  
41
} mtar_raw_header_t;
  
42
  
  
43
  
  
44
static unsigned round_up(unsigned n, unsigned incr) {
  
45
  return n + (incr - n % incr) % incr;
  
46
}
  
47
  
  
48
  
  
49
static unsigned checksum(const mtar_raw_header_t* rh) {
  
50
  unsigned i;
  
51
  unsigned char *p = (unsigned char*) rh;
  
52
  unsigned res = 256;
  
53
  for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) {
  
54
    res += p[i];
  
55
  }
  
56
  for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) {
  
57
    res += p[i];
  
58
  }
  
59
  return res;
  
60
}
  
61
  
  
62
  
  
63
static int tread(mtar_t *tar, void *data, unsigned size) {
  
64
  int err = tar->read(tar, data, size);
  
65
  tar->pos += size;
  
66
  return err;
  
67
}
  
68
  
  
69
  
  
70
static int twrite(mtar_t *tar, const void *data, unsigned size) {
  
71
  int err = tar->write(tar, data, size);
  
72
  tar->pos += size;
  
73
  return err;
  
74
}
  
75
  
  
76
  
  
77
static int write_null_bytes(mtar_t *tar, int n) {
  
78
  int i, err;
  
79
  char nul = '\0';
  
80
  for (i = 0; i < n; i++) {
  
81
    err = twrite(tar, &nul, 1);
  
82
    if (err) {
  
83
      return err;
  
84
    }
  
85
  }
  
86
  return MTAR_ESUCCESS;
  
87
}
  
88
  
  
89
  
  
90
static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) {
  
91
  unsigned chksum1, chksum2;
  
92
  
  
93
  /* If the checksum starts with a null byte we assume the record is NULL */
  
94
  if (*rh->checksum == '\0') {
  
95
    return MTAR_ENULLRECORD;
  
96
  }
  
97
  
  
98
  /* Build and compare checksum */
  
99
  chksum1 = checksum(rh);
  
100
  sscanf(rh->checksum, "%o", &chksum2);
  
101
  if (chksum1 != chksum2) {
  
102
    return MTAR_EBADCHKSUM;
  
103
  }
  
104
  
  
105
  /* Load raw header into header */
  
106
  sscanf(rh->mode, "%o", &h->mode);
  
107
  sscanf(rh->owner, "%o", &h->owner);
  
108
  sscanf(rh->size, "%o", &h->size);
  
109
  sscanf(rh->mtime, "%o", &h->mtime);
  
110
  h->type = rh->type;
  
111
  strcpy(h->name, rh->name);
  
112
  strcpy(h->linkname, rh->linkname);
  
113
  
  
114
  return MTAR_ESUCCESS;
  
115
}
  
116
  
  
117
  
  
118
static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) {
  
119
  unsigned chksum;
  
120
  
  
121
  /* Load header into raw header */
  
122
  memset(rh, 0, sizeof(*rh));
  
123
  sprintf(rh->mode, "%o", h->mode);
  
124
  sprintf(rh->owner, "%o", h->owner);
  
125
  sprintf(rh->size, "%o", h->size);
  
126
  sprintf(rh->mtime, "%o", h->mtime);
  
127
  rh->type = h->type ? h->type : MTAR_TREG;
  
128
  strcpy(rh->name, h->name);
  
129
  strcpy(rh->linkname, h->linkname);
  
130
  
  
131
  /* Calculate and write checksum */
  
132
  chksum = checksum(rh);
  
133
  sprintf(rh->checksum, "%06o", chksum);
  
134
  rh->checksum[7] = ' ';
  
135
  
  
136
  return MTAR_ESUCCESS;
  
137
}
  
138
  
  
139
  
  
140
const char* mtar_strerror(int err) {
  
141
  switch (err) {
  
142
    case MTAR_ESUCCESS     : return "success";
  
143
    case MTAR_EFAILURE     : return "failure";
  
144
    case MTAR_EOPENFAIL    : return "could not open";
  
145
    case MTAR_EREADFAIL    : return "could not read";
  
146
    case MTAR_EWRITEFAIL   : return "could not write";
  
147
    case MTAR_ESEEKFAIL    : return "could not seek";
  
148
    case MTAR_EBADCHKSUM   : return "bad checksum";
  
149
    case MTAR_ENULLRECORD  : return "null record";
  
150
    case MTAR_ENOTFOUND    : return "file not found";
  
151
  }
  
152
  return "unknown error";
  
153
}
  
154
  
  
155
  
  
156
static int file_write(mtar_t *tar, const void *data, unsigned size) {
  
157
  unsigned res = fwrite(data, 1, size, tar->stream);
  
158
  return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
  
159
}
  
160
  
  
161
static int file_read(mtar_t *tar, void *data, unsigned size) {
  
162
  unsigned res = fread(data, 1, size, tar->stream);
  
163
  return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
  
164
}
  
165
  
  
166
static int file_seek(mtar_t *tar, unsigned offset) {
  
167
  int res = fseek(tar->stream, offset, SEEK_SET);
  
168
  return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
  
169
}
  
170
  
  
171
static int file_close(mtar_t *tar) {
  
172
  fclose(tar->stream);
  
173
  return MTAR_ESUCCESS;
  
174
}
  
175
  
  
176
  
  
177
int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
  
178
  int err;
  
179
  mtar_header_t h;
  
180
  
  
181
  /* Init tar struct and functions */
  
182
  memset(tar, 0, sizeof(*tar));
  
183
  tar->write = file_write;
  
184
  tar->read = file_read;
  
185
  tar->seek = file_seek;
  
186
  tar->close = file_close;
  
187
  
  
188
  /* Assure mode is always binary */
  
189
  if ( strchr(mode, 'r') ) mode = "rb";
  
190
  if ( strchr(mode, 'w') ) mode = "wb";
  
191
  if ( strchr(mode, 'a') ) mode = "ab";
  
192
  /* Open file */
  
193
  tar->stream = fopen(filename, mode);
  
194
  if (!tar->stream) {
  
195
    return MTAR_EOPENFAIL;
  
196
  }
  
197
  /* Read first header to check it is valid if mode is `r` */
  
198
  if (*mode == 'r') {
  
199
    err = mtar_read_header(tar, &h);
  
200
    if (err != MTAR_ESUCCESS) {
  
201
      mtar_close(tar);
  
202
      return err;
  
203
    }
  
204
  }
  
205
  
  
206
  /* Return ok */
  
207
  return MTAR_ESUCCESS;
  
208
}
  
209
  
  
210
  
  
211
int mtar_close(mtar_t *tar) {
  
212
  return tar->close(tar);
  
213
}
  
214
  
  
215
  
  
216
int mtar_seek(mtar_t *tar, unsigned pos) {
  
217
  int err = tar->seek(tar, pos);
  
218
  tar->pos = pos;
  
219
  return err;
  
220
}
  
221
  
  
222
  
  
223
int mtar_rewind(mtar_t *tar) {
  
224
  tar->remaining_data = 0;
  
225
  tar->last_header = 0;
  
226
  return mtar_seek(tar, 0);
  
227
}
  
228
  
  
229
  
  
230
int mtar_next(mtar_t *tar) {
  
231
  int err, n;
  
232
  mtar_header_t h;
  
233
  /* Load header */
  
234
  err = mtar_read_header(tar, &h);
  
235
  if (err) {
  
236
    return err;
  
237
  }
  
238
  /* Seek to next record */
  
239
  n = round_up(h.size, 512) + sizeof(mtar_raw_header_t);
  
240
  return mtar_seek(tar, tar->pos + n);
  
241
}
  
242
  
  
243
  
  
244
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) {
  
245
  int err;
  
246
  mtar_header_t header;
  
247
  /* Start at beginning */
  
248
  err = mtar_rewind(tar);
  
249
  if (err) {
  
250
    return err;
  
251
  }
  
252
  /* Iterate all files until we hit an error or find the file */
  
253
  while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) {
  
254
    if ( !strcmp(header.name, name) ) {
  
255
      if (h) {
  
256
        *h = header;
  
257
      }
  
258
      return MTAR_ESUCCESS;
  
259
    }
  
260
    mtar_next(tar);
  
261
  }
  
262
  /* Return error */
  
263
  if (err == MTAR_ENULLRECORD) {
  
264
    err = MTAR_ENOTFOUND;
  
265
  }
  
266
  return err;
  
267
}
  
268
  
  
269
  
  
270
int mtar_read_header(mtar_t *tar, mtar_header_t *h) {
  
271
  int err;
  
272
  mtar_raw_header_t rh;
  
273
  /* Save header position */
  
274
  tar->last_header = tar->pos;
  
275
  /* Read raw header */
  
276
  err = tread(tar, &rh, sizeof(rh));
  
277
  if (err) {
  
278
    return err;
  
279
  }
  
280
  /* Seek back to start of header */
  
281
  err = mtar_seek(tar, tar->last_header);
  
282
  if (err) {
  
283
    return err;
  
284
  }
  
285
  /* Load raw header into header struct and return */
  
286
  return raw_to_header(h, &rh);
  
287
}
  
288
  
  
289
  
  
290
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) {
  
291
  int err;
  
292
  /* If we have no remaining data then this is the first read, we get the size,
  
293
   * set the remaining data and seek to the beginning of the data */
  
294
  if (tar->remaining_data == 0) {
  
295
    mtar_header_t h;
  
296
    /* Read header */
  
297
    err = mtar_read_header(tar, &h);
  
298
    if (err) {
  
299
      return err;
  
300
    }
  
301
    /* Seek past header and init remaining data */
  
302
    err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t));
  
303
    if (err) {
  
304
      return err;
  
305
    }
  
306
    tar->remaining_data = h.size;
  
307
  }
  
308
  /* Read data */
  
309
  err = tread(tar, ptr, size);
  
310
  if (err) {
  
311
    return err;
  
312
  }
  
313
  tar->remaining_data -= size;
  
314
  /* If there is no remaining data we've finished reading and seek back to the
  
315
   * header */
  
316
  if (tar->remaining_data == 0) {
  
317
    return mtar_seek(tar, tar->last_header);
  
318
  }
  
319
  return MTAR_ESUCCESS;
  
320
}
  
321
  
  
322
  
  
323
int mtar_write_header(mtar_t *tar, const mtar_header_t *h) {
  
324
  mtar_raw_header_t rh;
  
325
  /* Build raw header and write */
  
326
  header_to_raw(&rh, h);
  
327
  tar->remaining_data = h->size;
  
328
  return twrite(tar, &rh, sizeof(rh));
  
329
}
  
330
  
  
331
  
  
332
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) {
  
333
  mtar_header_t h;
  
334
  /* Build header */
  
335
  memset(&h, 0, sizeof(h));
  
336
  strcpy(h.name, name);
  
337
  h.size = size;
  
338
  h.type = MTAR_TREG;
  
339
  h.mode = 0664;
  
340
  /* Write header */
  
341
  return mtar_write_header(tar, &h);
  
342
}
  
343
  
  
344
  
  
345
int mtar_write_dir_header(mtar_t *tar, const char *name) {
  
346
  mtar_header_t h;
  
347
  /* Build header */
  
348
  memset(&h, 0, sizeof(h));
  
349
  strcpy(h.name, name);
  
350
  h.type = MTAR_TDIR;
  
351
  h.mode = 0775;
  
352
  /* Write header */
  
353
  return mtar_write_header(tar, &h);
  
354
}
  
355
  
  
356
  
  
357
int mtar_write_data(mtar_t *tar, const void *data, unsigned size) {
  
358
  int err;
  
359
  /* Write data */
  
360
  err = twrite(tar, data, size);
  
361
  if (err) {
  
362
    return err;
  
363
  }
  
364
  tar->remaining_data -= size;
  
365
  /* Write padding if we've written all the data for this file */
  
366
  if (tar->remaining_data == 0) {
  
367
    return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos);
  
368
  }
  
369
  return MTAR_ESUCCESS;
  
370
}
  
371
  
  
372
  
  
373
int mtar_finalize(mtar_t *tar) {
  
374
  /* Write two NULL records */
  
375
  return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2);
  
376
}
diff --git a/vendor/microtar-0.1.0/src/microtar.h b/vendor/microtar-0.1.0/src/microtar.h
  
1
/**
  
2
 * Copyright (c) 2017 rxi
  
3
 *
  
4
 * This library is free software; you can redistribute it and/or modify it
  
5
 * under the terms of the MIT license. See `microtar.c` for details.
  
6
 */
  
7
  
  
8
#ifndef MICROTAR_H
  
9
#define MICROTAR_H
  
10
  
  
11
#include <stdio.h>
  
12
#include <stdlib.h>
  
13
  
  
14
#define MTAR_VERSION "0.1.0"
  
15
  
  
16
enum {
  
17
  MTAR_ESUCCESS     =  0,
  
18
  MTAR_EFAILURE     = -1,
  
19
  MTAR_EOPENFAIL    = -2,
  
20
  MTAR_EREADFAIL    = -3,
  
21
  MTAR_EWRITEFAIL   = -4,
  
22
  MTAR_ESEEKFAIL    = -5,
  
23
  MTAR_EBADCHKSUM   = -6,
  
24
  MTAR_ENULLRECORD  = -7,
  
25
  MTAR_ENOTFOUND    = -8
  
26
};
  
27
  
  
28
enum {
  
29
  MTAR_TREG   = '0',
  
30
  MTAR_TLNK   = '1',
  
31
  MTAR_TSYM   = '2',
  
32
  MTAR_TCHR   = '3',
  
33
  MTAR_TBLK   = '4',
  
34
  MTAR_TDIR   = '5',
  
35
  MTAR_TFIFO  = '6'
  
36
};
  
37
  
  
38
typedef struct {
  
39
  unsigned mode;
  
40
  unsigned owner;
  
41
  unsigned size;
  
42
  unsigned mtime;
  
43
  unsigned type;
  
44
  char name[100];
  
45
  char linkname[100];
  
46
} mtar_header_t;
  
47
  
  
48
  
  
49
typedef struct mtar_t mtar_t;
  
50
  
  
51
struct mtar_t {
  
52
  int (*read)(mtar_t *tar, void *data, unsigned size);
  
53
  int (*write)(mtar_t *tar, const void *data, unsigned size);
  
54
  int (*seek)(mtar_t *tar, unsigned pos);
  
55
  int (*close)(mtar_t *tar);
  
56
  void *stream;
  
57
  unsigned pos;
  
58
  unsigned remaining_data;
  
59
  unsigned last_header;
  
60
};
  
61
  
  
62
  
  
63
const char* mtar_strerror(int err);
  
64
  
  
65
int mtar_open(mtar_t *tar, const char *filename, const char *mode);
  
66
int mtar_close(mtar_t *tar);
  
67
  
  
68
int mtar_seek(mtar_t *tar, unsigned pos);
  
69
int mtar_rewind(mtar_t *tar);
  
70
int mtar_next(mtar_t *tar);
  
71
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h);
  
72
int mtar_read_header(mtar_t *tar, mtar_header_t *h);
  
73
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size);
  
74
  
  
75
int mtar_write_header(mtar_t *tar, const mtar_header_t *h);
  
76
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size);
  
77
int mtar_write_dir_header(mtar_t *tar, const char *name);
  
78
int mtar_write_data(mtar_t *tar, const void *data, unsigned size);
  
79
int mtar_finalize(mtar_t *tar);
  
80
  
  
81
  
  
82
#endif