aboutsummaryrefslogtreecommitdiff
path: root/libbb/atlas_name_macro.c
blob: 0674fd0720f08d07bbcaf46dc5b3a058badefc3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "libbb.h"

#define URANDOM_DEV "/dev/urandom"

static char hex_chars[]= "0123456789abcdef";

char *atlas_name_macro(char *str)
{
	unsigned char c;
	int i, fd;
	size_t len;
	char *p, *in, *out;
	char buf[256];
	unsigned char random_buf[8];

	p= strchr(str, '$');
	if (p == NULL)
		return strdup(str);

	in= str;
	out= buf;

	while (*in)
	{
		p= strchr(in, '$');
		if (p == NULL)
		{
			strlcpy(out, in, buf+sizeof(buf)-out);
			break;
		}
		if (p != in)
		{
			len= p-in;

			if (len+1 > buf+sizeof(buf)-out)
				return NULL;
			memcpy(out, in, len);
			out[len]= '\0';
			
			out += len;
		}

		switch(p[1])
		{
		case 'p':
			snprintf(out, buf+sizeof(buf)-out, "%d",
				get_probe_id());
			break;
		case 't':
			snprintf(out, buf+sizeof(buf)-out, "%ld",
				(long)time(NULL));
			break;
		case 'r':
			/* We need to hex digits per byte in random_buf */
			if (sizeof(random_buf)*2+1 > buf+sizeof(buf)-out)
				return NULL;

			fd= open(URANDOM_DEV, O_RDONLY);

			/* Best effort, just ignore errors */
			if (fd != -1)
			{
				read(fd, random_buf, sizeof(random_buf));
				close(fd);
			}

			for (i= 0; i<sizeof(random_buf); i++)
			{
				c= random_buf[i];

				out[0]= hex_chars[(c >> 4) & 0xf];
				out[1]= hex_chars[c & 0xf];
				out += 2;
			}
			
			out[0]= '\0';
			break;		

		default:
			return NULL;
		}
		in= p+2;
		out += strlen(out);
	}

	return strdup(buf);
}