Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * IPC: Coda di messaggi, shell interattiva, mappatura in memoria, lista comandi.
- * PADRE: Creazione di n processi pari alle directory passate,
- * avvio della shell interattiva.
- * FIGLIO: accede solo alla propria directory, utilizza la mappatura
- * dei file in memoria per leggere il contenuto dei file regolari ed effettuare operazioni.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/mman.h>
- #include <dirent.h>
- #include <string.h>
- #include <fcntl.h>
- #define MSGSIZE sizeof(msg)-sizeof(long)
- #define BUFFSIZE 1024
- #define PARENT 2000
- /* elenco dei comandi */
- typedef enum{
- CMD_NUM,
- CMD_REPLY,
- CMD_SEARCH,
- CMD_TOTAL,
- CMD_ERR,
- CMD_EXIT
- }cmd;
- /* struttura dei messaggi scambiati*/
- typedef struct{
- long mtype;
- unsigned int n;
- char buffer[BUFFSIZE];
- cmd comando;
- }msg;
- /* codice del processo figlio*/
- void children(int qid, char * pathfile, int num){
- msg messaggio;
- DIR *dir;
- struct dirent* dp;
- struct stat statfile;
- unsigned int counter;
- int fd;
- char* str;
- if(chdir(pathfile) == -1){ //apre la directory passata
- perror("chdir");
- exit(1);
- }
- while(1){
- msgrcv(qid, &messaggio, MSGSIZE, num, 0);
- switch (messaggio.comando){
- /*num-files n: n di file regolari direttamente contenuti nella directory*/
- case CMD_NUM:
- dir = opendir(".");
- counter = 0;
- while((dp = readdir(dir))){
- if(((stat(dp->d_name, &statfile)) != -1) && S_ISREG(statfile.st_mode))
- counter++;
- }
- closedir(dir);
- messaggio.mtype = PARENT;
- messaggio.n = counter;
- messaggio.comando = CMD_REPLY;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- break;
- /*search char n f c: visualizza il numero di occorrenze del carattere <c>
- indicato nel file <f> specificato nella directory <n>.*/
- case CMD_SEARCH:
- if((fd = open(messaggio.buffer, O_RDONLY)) == -1){
- messaggio.comando = CMD_ERR;
- messaggio.mtype = PARENT;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- break;
- }
- if((stat(messaggio.buffer, &statfile)) == -1){
- messaggio.comando = CMD_ERR;
- messaggio.mtype = PARENT;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- break;
- }
- if((str = mmap(NULL, statfile.st_size, PROT_READ, MAP_SHARED, fd, 0)) == NULL){
- messaggio.comando = CMD_ERR;
- messaggio.mtype = PARENT;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- break;
- }
- counter = 0;
- for(int i = 0; str[i] != EOF; i++){
- if(str[i] == (char)messaggio.n)
- counter++;
- }
- messaggio.comando = CMD_REPLY;
- messaggio.mtype = PARENT;
- messaggio.n = counter;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- munmap(str, statfile.st_size);
- close(fd);
- break;
- /*total-size n: dim tot in byte dei file regolari direttamente contenuti nella directory*/
- case CMD_TOTAL:
- dir = opendir(".");
- counter = 0;
- while((dp = readdir(dir))){
- if(((stat(dp->d_name, &statfile)) != -1) && S_ISREG(statfile.st_mode))
- counter+=statfile.st_size;
- }
- closedir(dir);
- messaggio.mtype = PARENT;
- messaggio.n = counter;
- messaggio.comando = CMD_REPLY;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- break;
- /*q: uscita dal programma*/
- case CMD_EXIT:
- exit(0);
- break;
- }
- }
- }
- /* stampa a video un menu informativo contenente la lista dei comandi disponibili*/
- void help(){
- printf("----HELP MENU----\n");
- printf("1) num-files n: visualizza il numero di fle regolari\n\tdirettamente contenuti nella directory <n>.\n");
- printf("2)total-size n: visualizza la dimensione totale (in byte)\n\tdei fle regolari direttamente contenuti nella directory <n>.\n");
- printf("3)search n f c: visualizza il numero di occorrenze\n\tdel carattere <c>indicato nel file <f> specificato nella directory <n>.\n");
- printf("4) q: uscita.\n");
- printf("5) h: aiuto.\n");
- }
- int main(int argc, char **argv){
- /*dichiarazione variabili*/
- int nchild;//contatore dei figli creati
- int qid; //coda di messaggi
- struct stat statbuf;
- char buffer [BUFFSIZE];
- char quit = 0;
- char *token, *nomefile;
- int len, n;
- msg messaggio;
- /*controllo sui parametri*/
- if(argc<2){
- fprintf(stderr, "Utilizzo: %s <dir-1> <dir-2> <...>\n", argv[0]);
- exit(1);
- }
- /*creazione coda di messaggi*/
- if((qid = msgget(IPC_PRIVATE,IPC_CREAT|IPC_EXCL|0660))==-1){
- perror("msgget");
- exit(1);
- }
- /*creazione processi figli*/
- nchild = 0;
- for(int i=1; i<argc; i++){
- //controllo sul parametro passato. Verifica se corrisponde a directory
- if ( (stat(argv[i], &statbuf)==-1) || (!S_ISDIR(statbuf.st_mode)) ){
- fprintf(stderr, "Directory \"%s\" non valida. Salto al prossimo argomento.\n", argv[i]);
- continue;
- }
- nchild++;
- if(fork()==0)
- children(qid, argv[i], nchild);
- }
- if(nchild == 0){
- fprintf(stderr, "Nessuna cartella valida\n");
- exit(1);
- }
- /*avvia la shell interattiva */
- printf("Benvenuto nella shell interattiva. Digita q per uscire, h per aiuto.\n");
- sleep(1);
- while(1){
- printf("file-shell> ");
- fgets(buffer, BUFFSIZE, stdin);
- len = strlen(buffer);
- if (buffer[len-1] == '\n')
- buffer[len-1] = '\0';
- if((token = strtok(buffer, " "))){ //estrare il primo token, cioè il comando
- if(strcmp(token, "h")==0){
- help();
- }else if(strcmp(token, "num-files") == 0){
- if((token = strtok(NULL, " "))){
- n = atoi(token);
- if(n > 0 && n <= nchild){
- messaggio.mtype = n;
- messaggio.comando = CMD_NUM;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- msgrcv(qid, &messaggio, MSGSIZE, PARENT, 0);
- if(messaggio.comando == CMD_REPLY)
- printf("Numero di file regolari: %d\n", messaggio.n);
- }else
- fprintf(stderr, "Figlio non esistente\n");
- }else
- fprintf(stderr, "USE: list n\n");
- }else if(strcmp(token, "search") == 0){
- if((token = strtok(NULL, " "))){
- n = atoi(token);
- if(n > 0 && n <= nchild){
- if((token = strtok(NULL, " "))){
- nomefile = token;
- if((token = strtok(NULL, " "))){
- messaggio.mtype = n;
- messaggio.comando = CMD_SEARCH;
- strcpy(messaggio.buffer, nomefile);
- messaggio.n = token[0];
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- msgrcv(qid, &messaggio, MSGSIZE, PARENT, 0);
- if(messaggio.comando == CMD_REPLY)
- printf("Numero di occorrenze di %c: %d\n", token[0], messaggio.n);
- else
- fprintf(stderr, "Errore dal figlio %d\n", n);
- }
- }
- }else
- fprintf(stderr, "Figlio non esistente\n");
- }else
- fprintf(stderr, "USE search n nome-file carattere\n");
- }else if(strcmp(token, "total-size")==0){
- if((token = strtok(NULL, " "))){
- n = atoi(token);
- if(n > 0 && n <= nchild){
- messaggio.mtype = n;
- messaggio.comando = CMD_TOTAL;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- msgrcv(qid, &messaggio, MSGSIZE, PARENT, 0);
- if(messaggio.comando == CMD_REPLY)
- printf("Dimensione totale dei file nella cartella: %d bytes.\n", messaggio.n);
- else
- fprintf(stderr, "Errore dal figlio %d\n", n);
- }else
- fprintf(stderr, "Figlio non esistente\n");
- }
- }else if(strcmp(token, "q") == 0)
- break;
- else
- fprintf(stderr, "Comando non riconosciuto.\n");
- }
- }
- messaggio.comando = CMD_EXIT;
- for(int i = 1; i <= nchild; i++){
- messaggio.mtype = i;
- msgsnd(qid, &messaggio, MSGSIZE, 0);
- }
- //chiusura delle strutture
- msgctl(qid, IPC_RMID, NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement