1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "libbb.h"
22#include "bb_archive.h"
23
24struct fileblock {
25 struct fileblock *next;
26 char data[TAR_BLOCK_SIZE];
27};
28
29static void writeheader(const char *path, struct stat *sb, int type)
30{
31 struct tar_header_t header;
32
33 memset(&header, 0, TAR_BLOCK_SIZE);
34 strcpy(header.name, path);
35 sprintf(header.mode, "%o", sb->st_mode & 0777);
36
37 sprintf(header.uid, "%o", sb->st_uid & 07777777);
38 sprintf(header.gid, "%o", sb->st_gid & 07777777);
39 sprintf(header.size, "%o", (unsigned)sb->st_size);
40 sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL);
41 header.typeflag = type;
42 chksum_and_xwrite_tar_header(STDOUT_FILENO, &header);
43}
44
45static void archivefile(const char *path)
46{
47 struct fileblock *start, *cur;
48 struct fileblock **prev = &start;
49 int fd, r;
50 unsigned size = 0;
51 struct stat s;
52
53
54 fd = open(path, O_RDONLY);
55 if (fd == -1) {
56
57 return;
58 }
59 do {
60 cur = xzalloc(sizeof(*cur));
61 *prev = cur;
62 prev = &cur->next;
63 r = full_read(fd, cur->data, TAR_BLOCK_SIZE);
64 if (r > 0)
65 size += r;
66 } while (r == TAR_BLOCK_SIZE);
67
68
69 fstat(fd, &s);
70 close(fd);
71 s.st_size = size;
72 writeheader(path, &s, '0');
73
74
75 for (cur = start; (int)size > 0; size -= TAR_BLOCK_SIZE) {
76 xwrite(STDOUT_FILENO, cur->data, TAR_BLOCK_SIZE);
77 start = cur;
78 cur = cur->next;
79 free(start);
80 }
81}
82
83static void archivejoin(const char *sub, const char *name)
84{
85 char path[sizeof(long long)*3 + sizeof("/cmdline")];
86 sprintf(path, "%s/%s", sub, name);
87 archivefile(path);
88}
89
90
91
92
93
94int smemcap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
95int smemcap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
96{
97 DIR *d;
98 struct dirent *de;
99
100 xchdir("/proc");
101 d = xopendir(".");
102
103 archivefile("meminfo");
104 archivefile("version");
105 while ((de = readdir(d)) != NULL) {
106 if (isdigit(de->d_name[0])) {
107 struct stat s;
108 memset(&s, 0, sizeof(s));
109 s.st_mode = 0555;
110 writeheader(de->d_name, &s, '5');
111 archivejoin(de->d_name, "smaps");
112 archivejoin(de->d_name, "cmdline");
113 archivejoin(de->d_name, "stat");
114 }
115 }
116
117 if (ENABLE_FEATURE_CLEAN_UP)
118 closedir(d);
119
120 return EXIT_SUCCESS;
121}
122