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;
}
|