112 lines
2.3 KiB
C
112 lines
2.3 KiB
C
/*
|
|
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, "%08o", mode);
|
|
sprintf(header + 108, "%08o", uid);
|
|
sprintf(header + 116, "%08o", gid);
|
|
sprintf(header + 124, "%012o", size);
|
|
sprintf(header + 136, "%08o", 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, 040555, 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;
|
|
}
|