File: smemcap.c

package info (click to toggle)
smem 0.9-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 144 kB
  • ctags: 84
  • sloc: python: 539; ansic: 81; sh: 10; makefile: 2
file content (112 lines) | stat: -rw-r--r-- 2,398 bytes parent folder | download
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 smem - a tool for meaningful memory reporting

 Copyright 2008-2009 Matt Mackall <mpm@selenic.com>

 This software may be used and distributed according to the terms of
 the GNU General Public License version 2 or later, incorporated
 herein by reference.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <memory.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>

struct fileblock;
struct fileblock {
	char data[512];
	struct fileblock *next;
};

int writeheader(int destfd, const char *path, int mode, int uid, int gid,
		int size, int mtime, int type)
{
	char header[512];
	int i, sum;

	memset(header, 0, 512);

	sprintf(header, "%s", path);
	sprintf(header + 100, "%07o\0", mode & 0777);
	sprintf(header + 108, "%07o\0", uid);
	sprintf(header + 116, "%07o\0", gid);
	sprintf(header + 124, "%011o\0", size);
	sprintf(header + 136, "%07o\0", mtime);
	sprintf(header + 148, "        %1d", type);

	/* fix checksum */
	for (i = sum = 0; i < 512; i++)
		sum += header[i];
	sprintf(header + 148, "%06o\0 %1d", sum, type);

	return write(destfd, header, 512);
}

int archivefile(const char *path, int destfd)
{
	struct fileblock *start, *cur;
	struct fileblock **prev = &start;
	int fd, r, size = 0;
	struct stat s;

	/* buffer and stat the file */
	fd = open(path, O_RDONLY);
	fstat(fd, &s);

	do {
		cur = calloc(1, sizeof(struct fileblock));
		*prev = cur;
		prev = &cur->next;
		r = read(fd, cur->data, 512);
		if (r > 0)
			size += r;
	} while (r == 512);

	close(fd);

	/* write archive header */
	writeheader(destfd, path, s.st_mode, s.st_uid,
		    s.st_gid, size, s.st_mtime, 0);

	/* dump file contents */
	for (cur = start; size > 0; size -= 512) {
		write(destfd, cur->data, 512);
		start = cur;
		cur = cur->next;
		free(start);
	}
}

int archivejoin(const char *sub, const char *name, int destfd)
{
	char path[256];
	sprintf(path, "%s/%s", sub, name);
	return archivefile(path, destfd);
}

int main(int argc, char *argv[])
{
	int fd;
	DIR *d;
	struct dirent *de;

	chdir("/proc");
	archivefile("meminfo", 1);
	archivefile("version", 1);

	d = opendir(".");
	while (de = readdir(d))
		if (de->d_name[0] >= '0' && de->d_name[0] <= '9') {
			writeheader(1, de->d_name, 0555, 0, 0, 0, 0, 5);
			archivejoin(de->d_name, "smaps", 1);
			archivejoin(de->d_name, "cmdline", 1);
			archivejoin(de->d_name, "stat", 1);
		}

	return 0;
}