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