1 #include "bsdtar_platform.h"
2
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6
7 #include "hexify.h"
8 #include "warnp.h"
9
10 #include "hexlink.h"
11
12 /**
13 * hexlink_write(path, buf, buflen):
14 * Convert ${buf} (of length ${buflen}) into hexadecimal and create a link
15 * from ${path} pointing at it.
16 */
17 int
hexlink_write(const char * path,const uint8_t * buf,size_t buflen)18 hexlink_write(const char * path, const uint8_t * buf, size_t buflen)
19 {
20 char * hexbuf;
21
22 /* Allocate memory for buffer. */
23 if ((hexbuf = malloc(buflen * 2 + 1)) == NULL)
24 goto err0;
25
26 /* Convert ${buf} to hex. */
27 hexify(buf, hexbuf, buflen);
28
29 /* Create the symlink. */
30 if (symlink(hexbuf, path)) {
31 warnp("symlink(%s, %s)", hexbuf, path);
32 goto err1;
33 }
34
35 /* Free allocated memory. */
36 free(hexbuf);
37
38 /* Success! */
39 return (0);
40
41 err1:
42 free(hexbuf);
43 err0:
44 /* Failure! */
45 return (-1);
46 }
47
48 /**
49 * hexlink_read(path, buf, buflen):
50 * Read the link ${path}, which should point to a hexadecimal string of
51 * length 2 * ${buflen}; and parse this into the provided buffer. In the
52 * event of an error, return with errno == ENOENT iff the link does not
53 * exist.
54 */
55 int
hexlink_read(const char * path,uint8_t * buf,size_t buflen)56 hexlink_read(const char * path, uint8_t * buf, size_t buflen)
57 {
58 char * hexbuf;
59 ssize_t rc;
60
61 /* Allocate memory for buffer. */
62 if ((hexbuf = malloc(buflen * 2 + 1)) == NULL)
63 goto err0;
64
65 /* Attempt to read the link. */
66 if ((rc = readlink(path, hexbuf, buflen * 2)) == -1) {
67 /* Couldn't read the link. */
68 goto err1;
69 }
70
71 /* Is the link the correct length? */
72 if ((size_t)rc != (buflen * 2)) {
73 warn0("Link is incorrect length: %s", path);
74 goto err1;
75 }
76
77 /* NUL-terminate. */
78 hexbuf[rc] = '\0';
79
80 /* Parse the link value into the provided buffer. */
81 if (unhexify(hexbuf, buf, buflen)) {
82 warn0("Cannot parse link as hexadecimal: %s -> %s",
83 path, hexbuf);
84 goto err1;
85 }
86
87 /* Free allocated memory. */
88 free(hexbuf);
89
90 /* Success! */
91 return (0);
92
93 err1:
94 free(hexbuf);
95 err0:
96 /* Failure! */
97 return (-1);
98 }
99