/*
Grep Dir v0.2
Descrizione: Grep dir cerca una o due stringhe (in tal caso effettuando una ricerca incrociata)
nella directory scelta e/o in tutte le sue sub-directory.
Con il parametro -s infatti è possibile effettuare la ricerca solo ina una determinata dir
Autore: __GiReX__
Linguaggio: C++
Sito: http://girex.altervista.org/
Compile with: $ g++ grep_dir2.cpp -o grep-dir
Or under Windows with Dev-Cpp
Thanks to: Style HdS619 for beta-testing and moral support!
30/12/07 02.14
*/
#define log_file "grep_dir_log.txt" // Modificare a proprio piacimento
#ifdef WIN32 // Direttive del pre-processore per cambiare lo slash
#define slash "\\" // delle dir in base al SO
#else
#define slash "/"
#endif
#include <iostream>
#include <fstream>
#include <dirent.h>
using namespace std;
bool single_dir = false;
int first_change(char *dir);
int check_dir(char *d, char *match, char *match1);
int check_file(char *file, char *dir, char *match, char *match1);
void display(char *buffer, char *file, char *dir, int riga);
void usage(char *prog);
int main(int argc, char *argv[])
{
int error = 1;
if(argc == 3) { // Controllo dei parametri
if(!first_change(argv[1])) error = check_dir(argv[1], argv[2], NULL);
} else
if(argc == 4 && strcmp(argv[1], "-s")) {
if(!first_change(argv[1])) error = check_dir(argv[1], argv[2], argv[3]);
} else
if(argc == 4 && !strcmp(argv[1], "-s")) {
if(!first_change(argv[2]))
{
single_dir = true;
error = check_dir(argv[2], argv[3], NULL);
}
} else
if(argc == 5 && !strcmp(argv[1], "-s")) {
if(!first_change(argv[2]))
{
single_dir = true;
error = check_dir(argv[2], argv[3], argv[4]);
}
} else {
usage(argv[0]);
return -1;
}
if(!error) cout << "File " << log_file << " creato con successo!\n";
else cout << "Sono stati riscontrati degli errori durante l'esecuzione del programma!\n";
return 0;
}
int first_change(char *dir)
{
if(chdir(dir) != 0) // Cambio directory di lavoro
{ // in quella passata come argomento
cout << endl << "Impossibile cambiare la direcory: " << dir << endl;
return -1;
}
return 0;
}
int check_dir(char *d, char *match, char *match1) // Funzione ricorsiva
{ // essenziale per trovare le sub-dir
DIR *dir;
dirent *dinfo;
char current[FILENAME_MAX];
getcwd(current, FILENAME_MAX); // Ottengo la directory corrente
if((dir = opendir(current)) == 0) { // Apro la directory
cout << "Impossibile aprire la directory: " << d << endl;
return -1; }
while(dinfo = readdir(dir)) // Scorro la directory
{
if(!strcmp(dinfo->d_name, ".") || !strcmp(dinfo->d_name, "..") ||
!strcmp(dinfo->d_name, "grep_dir_log.txt")) continue;
if(chdir(dinfo->d_name) != 0) check_file(dinfo->d_name, d, match, match1); // Se non è 1 dir, controllo il file
else {
if(single_dir == true) { chdir(".."); continue; } // Parametro -s, non cambio dir
strcpy(current, d);
strcat(current, "/");
strcat(current, dinfo->d_name); // Ottengo una nuova dir
check_dir(current, match, match1); // La funzione richiama se stessa
// con dir differente
if(chdir("..") != 0) {
cout << "Impossibile spostarsi nella cartella superiore\n"; // Torno nella dir superiore
return -2; }
}
}
closedir(dir);
return 0;
}
int check_file(char *file, char *dir, char *match, char *match1)
{
bool single_match = true;
ifstream current(file, ios::in);
char buffer[1024];
if(!current.is_open()) {
cout << "Errore nell'apertura del file: " << file << endl;
return -1; }
if(match1 == NULL) single_match = true;
else single_match = false;
for(int i = 1; current.good(); i++)
{
current.getline(buffer, sizeof(buffer)); // Scorro tutte le righe per trovare il
if(single_match == true && strstr(buffer, match) || // match
single_match == false && strstr(buffer, match) && strstr(buffer, match1))
display(buffer, file, dir, i); // Trovato match, loggo file dir e riga
memset(buffer, 0, sizeof(buffer)); // Pulisco buffer
}
current.clear();
current.close();
return 0;
}
void display(char *buffer, char *file, char *dir, int riga)
{
ofstream log(log_file, ios::out | ios::app);
log << "---------------------------------------------------------------\n"
<< "Nome file:\t" << file << endl
<< "Sub directory:\t" << dir << endl
<< "Riga numero:\t" << riga << endl
<< endl << buffer << endl
<< "---------------------------------------------------------------\n\n";
log.close();
}
void usage(char *prog)
{
cout << endl
<< "Grep Dir v0.2 by __GiReX__ search string(s) il all sub-directory\n"
<< "and display file, line and sub-dir where it match the string(s)\n\n"
<< "Usage: " << prog << " <directory> <string> [string2] \n"
<< "Usage: " << prog << " -s <directory> <string> [string2]\n\n"
<< "Example: " << prog << " ~/source \"#include <stdio.h>\"\n"
<< "Example: " << prog << " -s ~/php WHERE $id\n\n"
<< "-s : il parametro -s specifica che si intende lavorarare solo\n"
<< "nella directory specificata e non in tutte le sue sub-directory\n\n"
<< "[string2] : specificare la seconda stringa per effettuare una\n"
<< "ricerca incrociata e' opzionale\n\n"
<< "Se tra virgolette \"\" si possono anche passare come argomento intere frasi\n"
<< endl;
}