Subversion Repositories wimsdev

Rev

Rev 15779 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 1
/*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
2
 *
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
17
 
8100 bpr 18
/* Computes class connection count (unit: student-minutes) */
10 reyssat 19
 
8100 bpr 20
#include "../Lib/libwims.h"
10 reyssat 21
 
8149 bpr 22
/* The maximal number of sessions within one day */
10 reyssat 23
#define MAX_SESSIONS (128*1024)
8149 bpr 24
/* The maximal number of classes within one day */
10 reyssat 25
#define MAX_CLASSES 8192
8149 bpr 26
/* At least these minutes will be counted for each session */
17094 guerimand 27
#define MIN_CONNECT 1
8149 bpr 28
/* Add this number of minutes to each session */
10 reyssat 29
#define MIN_ADD 1
8149 bpr 30
/* Accounting discontinues after this number of idle minutes */
10 reyssat 31
#define MAX_LAPSE 15
32
 
33
struct {
17094 guerimand 34
  char s[4], u[32], cl[20];
35
  int start, end, cnt;
36
 
10 reyssat 37
} ses[MAX_SESSIONS];
38
int sescnt;
39
 
40
char *datestr;
41
 
42
struct cls {
17094 guerimand 43
  char cl[20];
44
  int cnt;
10 reyssat 45
} cls[MAX_CLASSES];
46
int clscnt;
47
 
8149 bpr 48
/* Read/write to a file with variable parms to print filename */
8899 bpr 49
/* same in Interfaces/common.c and wlogdaccessfile */
50
static
10 reyssat 51
void accessfile(char *content, char *type, char *s,...)
52
{
12248 bpr 53
  va_list vp;
54
  char buf[MAX_LINELEN+1];
55
  FILE *f;
56
  int l;
10 reyssat 57
 
12248 bpr 58
  va_start(vp,s);
59
  vsnprintf(buf,sizeof(buf),s,vp);
60
  va_end(vp);
61
  f=fopen(buf,type); if(f==NULL) {
62
    if(*type=='r') content[0]=0;
63
    return;
64
  }
65
  switch(*type) {
66
    case 'a':
67
    case 'w': {
68
      l=strlen(content); fwrite(content,1,l,f); break;
10 reyssat 69
    }
12248 bpr 70
    case 'r': {
71
      l=fread(content,1,MAX_LINELEN-1,f);
72
      if(l>0 && l<MAX_LINELEN) content[l]=0;
73
      else content[0]=0;
74
      break;
7079 bpr 75
    }
12248 bpr 76
   default: {
77
      content[0]=0; break;
78
   }
79
  }
80
  fclose(f);
10 reyssat 81
}
8149 bpr 82
/* recursively generate a directory structure */
8100 bpr 83
void mkdirs2(char *s)
10 reyssat 84
{
12248 bpr 85
  struct stat st;
86
  char *buf;
87
  if(stat(s,&st)==-1) {
88
  if(strrchr(s,'/')!=NULL) {
89
    buf=xmalloc(strlen(s)+1);
90
    ovlstrcpy(buf,s); *strrchr(buf,'/')=0;
91
    mkdirs2(buf); free(buf);
92
  }
93
  mkdir(s,-1);
94
  }
10 reyssat 95
}
96
 
17094 guerimand 97
/* line format is :
98
YYYYMMDD.HH:MM:SS session IP cmd module (time) login,class
99
time is displayed only for long request
100
*/
8899 bpr 101
static
10 reyssat 102
void oneline(char *p)
103
{
17094 guerimand 104
  char tbuf[8], sbuf[8], ubuf[32], cl[20];
105
  char *p1  /*, *p2*/;
106
  int i,t;
12248 bpr 107
  memmove(tbuf,p+9,6); tbuf[2]=tbuf[5]=0;
108
  t=atoi(tbuf)*60+atoi(tbuf+3);
109
  memmove(sbuf,p+18,4); sbuf[4]=0;
110
  p1=strchr(p,','); if(p1==NULL) return;
111
  if(!isdigit(*(p1+1))) return;
17094 guerimand 112
  snprintf(cl,sizeof(cl),"%s",p1+1);
12248 bpr 113
  *p1=0; for(p1--;p1>p && !isspace(*(p1-1)); p1--);
114
  snprintf(ubuf,sizeof(ubuf),"%s",p1);
115
  for(i=0;i<sescnt;i++) {
17094 guerimand 116
    if(memcmp(cl,ses[i].cl,20)==0 && memcmp(sbuf,ses[i].s,4)==0 &&
12248 bpr 117
        ses[i].end>=t-MAX_LAPSE) {
118
      ses[i].end=t; return;
10 reyssat 119
    }
12248 bpr 120
  }
121
  if(sescnt>=MAX_SESSIONS) return;
17094 guerimand 122
  memmove(ses[sescnt].s,sbuf,4);
123
  memmove(ses[sescnt].cl,cl,20);
12248 bpr 124
  ses[sescnt].start=ses[sescnt].end=t;
125
  snprintf(ses[sescnt].u,sizeof(ses[sescnt].u),"%s",ubuf);
126
  sescnt++;
10 reyssat 127
}
128
 
129
void onefile(char *fname)
130
{
12248 bpr 131
  FILE *f;
132
  long l;
133
  char *fbuf, *p1, *p2, *p3;
134
  l=filelength(fname); if(l<=0) return;
135
  f=fopen(fname,"r"); if(f==NULL) return;
136
  fbuf=xmalloc(l+16); (void)fread(fbuf,1,l,f); fclose(f); fbuf[l]=0;
137
  for(p1=fbuf; *p1; p1=p2) {
138
  p2=strchr(p1,'\n'); if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
139
  p3=strchr(p1,','); if(p3==NULL) continue;
140
  if(strncmp(p1,datestr,8)!=0) continue;
141
  oneline(p1);
142
  }
10 reyssat 143
}
144
 
145
void classaccount(void)
146
{
12248 bpr 147
  int i,j;
148
  clscnt=0;
149
  for(i=0;i<sescnt;i++) {
150
  ses[i].cnt=ses[i].end-ses[i].start+MIN_ADD;
151
  if(ses[i].cnt<MIN_CONNECT) ses[i].cnt=MIN_CONNECT;
152
  for(j=0;j<clscnt && ses[i].cl!=cls[j].cl;j++);
153
  if(j<clscnt) cls[j].cnt+=ses[i].cnt;
154
  else
155
    if(clscnt<MAX_CLASSES) {
17094 guerimand 156
      memmove(cls[clscnt].cl,ses[i].cl,20);
12248 bpr 157
      cls[clscnt].cnt=ses[i].cnt;
158
      clscnt++;
10 reyssat 159
    }
12248 bpr 160
  }
10 reyssat 161
}
162
 
163
int clscmp(const void *c1, const void *c2)
164
{
12248 bpr 165
  struct cls *cl1, *cl2;
166
  cl1=(struct cls *) c1; cl2=(struct cls *) c2;
167
  return cl1->cl-cl2->cl;
10 reyssat 168
}
169
 
170
void output(void)
171
{
12248 bpr 172
  char *p, buf[1024], dbuf[1024];
173
  int i,t;
174
  p=getenv("ccsum_outdir"); if(p==NULL || *p==0) return;
175
  for(i=0;i<sescnt;i++) {
17094 guerimand 176
    snprintf(dbuf,sizeof(dbuf),"%s/%s",p,ses[i].cl);
8100 bpr 177
    mkdirs2(dbuf);
7079 bpr 178
    snprintf(buf,sizeof(buf),"%s.%02d:%02d %d\n",
12248 bpr 179
       datestr,ses[i].start/60,ses[i].start%60,ses[i].cnt);
7079 bpr 180
    accessfile(buf,"a","%s/%s",dbuf,ses[i].u);
12248 bpr 181
  }
182
  snprintf(dbuf,sizeof(dbuf),"%s/bydate/%.4s",p,datestr);
183
  mkdirs2(dbuf);
184
  snprintf(dbuf+strlen(dbuf),sizeof(dbuf)-strlen(dbuf),"/%.2s",datestr+4);
185
  t=0;
186
  qsort(cls,clscnt,sizeof(cls[0]),clscmp);
187
  for(i=0;i<clscnt;i++) {
7079 bpr 188
    snprintf(buf,sizeof(buf),"%s %d\n",datestr,cls[i].cnt);
17094 guerimand 189
    accessfile(buf,"a","%s/%s/.total",p,cls[i].cl);
190
    snprintf(buf,sizeof(buf),"%s %s %d\n",datestr+4,cls[i].cl,cls[i].cnt);
7079 bpr 191
    accessfile(buf,"a","%s",dbuf);
192
    t+=cls[i].cnt;
12248 bpr 193
  }
194
  snprintf(buf,sizeof(buf),"%s %d %d\n",datestr,t,(t+30)/60);
195
  accessfile(buf,"a","%s/done",p);
10 reyssat 196
}
197
 
198
int main(int argc, char *argv[])
199
{
12248 bpr 200
  sescnt=0;
201
  if(argc<2) return 1;
202
  datestr=getenv("ccsum_date");
203
  if(datestr==NULL || strlen(datestr)!=8) return 2;
204
  onefile(argv[1]);
205
  classaccount();
206
  output();
207
  return 0;
10 reyssat 208
}
209