01: #include<stdio.h>
02: #include<stdlib.h>
03: #include<string.h>
04: 
05: struct log {
06:   char ip[16];
07:   char comando[501];
08:   int response, bytes;
09: };
10: 
11: int leggi_riga_log(FILE *fp, struct log *dest)
12: {
13:   // la stringa di formato riflette come e' fatta una riga di logo ovvero una
14:   // stringa senza spazi, uno spazio, una stringa tra ' e ', uno spazio, un
15:   // intero, uno spazio e un ultimo intero
16:   // si noti come %[^'] legge una stringa fino al primo ' escluso
17:   int val = fscanf(fp,"%s '%[^']' %d %d\n", dest->ip, dest->comando, &dest->response, &dest->bytes);
18: 
19:   return val==4?0:1;
20: }
21: 
22: struct log *leggi_log(const char *filename, int *n)
23: {
24:   struct log *dati=NULL;
25:   struct log tmp;
26:   FILE *fp=fopen(filename, "r");
27:   if(!fp)
28:   {
29:     perror("");
30:     exit(EXIT_FAILURE);
31:   }
32: 
33:   // inizializzo contatore righe ovvero dimensione array
34:   *n=0;
35:   while(!leggi_riga_log(fp, &tmp))
36:   {
37:     // printf("Ho letto %s %s %d %d\n", tmp.ip, tmp.comando, tmp.response, tmp.bytes); // DEBUG
38:     ++*n; // se ho letto una nuova riga aggiorno il numero di righe dell'array
39:     // e provvedo ad allargarlo con realloc()
40:     dati=realloc(dati, *n*sizeof(struct log));
41:     if(!dati)
42:     {
43:       perror("");
44:       exit(EXIT_FAILURE);
45:     }
46:     dati[*n-1]=tmp; // scrivo nell'ultimo elemento dell'array quanto letto
47:   }
48: 
49:   return dati;
50: 
51: }
52: 
53: int method(const struct log *dati, const int n, const char *command)
54: {
55:   int i, nc=0;
56:   for(i=0; i < n; ++i)
57:     if(!strncmp(dati[i].comando, command, strlen(command)))
58:   ++nc;
59: 
60:   return nc;
61: }
62: 
63: int bytes(const struct log *dati, const int n)
64: {
65:   int i, bytes=0;
66:   for(i=0; i < n; ++i)
67:     bytes += dati[i].bytes;
68: 
69:   return bytes;
70: }
71: 
72: int main(int argc, char **argv){
73: 
74:   int ndati;
75:   struct log *dati=leggi_log("access.log", &ndati);
76: 
77:   printf("Ho letto %d righe:\n", ndati);
78:   int i;
79:   for(i=0; i < ndati; ++i)
80:     printf("%s\t%s %d %d\n", dati[i].ip, dati[i].comando, dati[i].response, dati[i].bytes);
81: 
82:   int traffico=bytes(dati, ndati);
83:   printf("Ho trasferito complessivamente %d bytes\n", traffico);
84: 
85:   int nget=method(dati, ndati, "GET");
86:   printf("Nel log ci sono %d comandi 'GET'\n", nget);
87: 
88:   return 0;
89: }
90: 
91: