#include <dirent.h>
#include "fcntl.h"
#include <string>
#include <fstream>
using namespace std;
#define srccount 5
#define objcount 2
int countfiles(char *path, int& todo, int& done);
int dft(char *name);
int findproc(char *name);
int main() {
char *path, *action;
char line[256];
char *est;
est = "";
int done = 0, todo = 0, percent = 0;
path = "/usr/tmp/portage/";
struct dirent *entry; //This structure will hold file information
struct stat file_status; //This structure will be used to query file status
DIR *dir = opendir(path); //This pointer references the directory stream
printf("Emerge Progress v4.20 C++:\n");
//Make sure we have a directory stream pointer
if (!dir) { perror("opendir failure"); exit(1); }
chdir(path);
while ( (entry = readdir(dir)) != NULL) {
//Don't bother with the .. and . directories
if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
//Get the status info for the current file
if (stat(entry->d_name, &file_status) == 0) {
//Is this a directory, or a file?
if (S_ISDIR(file_status.st_mode)) {
strcpy(line,entry->d_name);
strcat(line,"/work");
todo = 0; done = 0;
if (countfiles(line,todo,done) == 1) { if (todo == 0) { percent=0; } else { percent=100 * done / todo; }
if (done > todo) {
todo = done++;
est = "~";
percent=100 * done / todo;}
//Is it running?
if (findproc(entry->d_name) == 1) { action="C"; } else { action="X"; }
printf(" * [%s] %s: %d/%d - %s%d%\n",action,entry->d_name,done,todo,est,percent);
}
chdir(path);
}
}
}
}
//Make sure we close the directory stream
if (closedir(dir) == -1) { perror("closedir failure"); exit(1); }
}
int countfiles(char *path, int& T, int& D) {
int c = 0,res = 0;
struct dirent *entry;
struct stat file_status;
DIR *dir = opendir(path);
if (!dir) { return 0; }
//Change directory to the given path
chdir(path);
//Loop through all files and directories
while ( (entry = readdir(dir)) != NULL) {
//Don't bother with the .. and . directories
if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
//Get the status info for the current file
if (stat(entry->d_name, &file_status) == 0) {
//Is this a directory, or a file?
if (S_ISDIR(file_status.st_mode)) {
//Call countfiles again (recursion) and add the result to the count total
countfiles(entry->d_name,T,D);
chdir("..");
} else {
//We've found a file, increment the count
res=dft(entry->d_name);
if (res==1) { T=T+1; } else if (res==2) { D=D+1; }
}
}
}
}
//Make sure we close the directory stream
if (closedir(dir) == -1) { perror("closedir failure"); exit(1); }
//Return the file count
return 1;
}
int dft(char *name)
{
//Find out file type..
//0= none
//1= todo
//2= done
int c;
char * tmp;
char *src[] = {".c/",".cpp/",".C/",".java/",".cc/"};
char *obj[] = {".o/",".class/"};
strcpy(tmp,name);
strcat(tmp,"/");
for(c=0; c<srccount;++c){ if (strstr(tmp,src[c]) !=NULL) { return 1; } }
for(c=0; c<objcount;++c){ if (strstr(tmp,obj[c]) !=NULL) { return 2; } }
//Neither
return 0;
}
int findproc(char *name)
{
//Find the proc of portage :)
int c = 0;
char *res;
char *path, *tmp;
char buffer[256];
path = "/proc/";
struct dirent *entry;
struct stat file_status;
DIR *dir = opendir(path);
if (!dir) { return 0; }
//Change directory to the given path
chdir(path);
//Loop through all files and directories
while ( (entry = readdir(dir)) != NULL) {
//Don't bother with the .. and . directories
if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
//Get the status info for the current file
if (stat(entry->d_name, &file_status) == 0) {
//Is this a directory, or a file?
if (S_ISDIR(file_status.st_mode)) {
chdir(entry->d_name);
ifstream rfile ("cmdline");
if (rfile.is_open()) {
rfile.getline (buffer,100);
if (strstr(buffer,name) != NULL) { return 1; }
}
rfile.close();
chdir("..");
}
}
}
}
//Make sure we close the directory stream
if (closedir(dir) == -1) { perror("closedir failure"); exit(1); }
//Return the file count
return 0;
}