/* smem - a tool for meaningful memory reporting Copyright 2008-2009 Matt Mackall 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 #include #include #include #include #include #include #include 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; }