Subversion Repositories wimsdev

Rev

Rev 7079 | Rev 8149 | Go to most recent revision | 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
 
20
#include "../wimsdef.h"
21
#include "../includes.h"
8100 bpr 22
#include "../Lib/libwims.h"
10 reyssat 23
 
7079 bpr 24
    /* The maximal number of sessions within one day */
10 reyssat 25
#define MAX_SESSIONS (128*1024)
7079 bpr 26
    /* The maximal number of classes within one day */
10 reyssat 27
#define MAX_CLASSES 8192
7079 bpr 28
    /* At least these minutes will be counted for each session */
10 reyssat 29
#define MIN_CONNECT 2
7079 bpr 30
    /* Add this number of minutes to each session */
10 reyssat 31
#define MIN_ADD 1
7079 bpr 32
    /* Accounting discontinues after this number of idle minutes */
10 reyssat 33
#define MAX_LAPSE 15
34
 
35
struct {
36
    char s[4], u[32];
37
    int cl, start, end, cnt;
38
} ses[MAX_SESSIONS];
39
int sescnt;
40
 
41
char *datestr;
42
 
43
struct cls {
44
    int cl, cnt;
45
} cls[MAX_CLASSES];
46
int clscnt;
47
 
8100 bpr 48
/*
10 reyssat 49
void *xmalloc(size_t n)
50
{
51
    void *p;
52
    p=malloc(n);
53
    if(p==NULL) {
7079 bpr 54
    fprintf(stderr,"Malloc failure."); exit(1);
10 reyssat 55
    }
56
    return p;
57
}
8100 bpr 58
*/
7079 bpr 59
    /* Points to the end of the word */
8100 bpr 60
/*
10 reyssat 61
char *find_word_end(char *p)
62
{
63
    int i;
64
    for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
65
    return p;
66
}
8100 bpr 67
*/
7079 bpr 68
    /* Strips leading spaces */
8100 bpr 69
/*
10 reyssat 70
char *find_word_start(char *p)
71
{
72
    int i;
73
    for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
74
    return p;
75
}
8100 bpr 76
*/
7079 bpr 77
    /* Read/write to a file with variable parms to print filename */
10 reyssat 78
void accessfile(char *content, char *type, char *s,...)
79
{
80
    va_list vp;
81
    char buf[MAX_LINELEN+1];
82
    FILE *f;
83
    int l;
84
 
85
    va_start(vp,s);
86
    vsnprintf(buf,sizeof(buf),s,vp);
87
    va_end(vp);
88
    f=fopen(buf,type); if(f==NULL) {
7079 bpr 89
    if(*type=='r') content[0]=0; return;
10 reyssat 90
    }
91
    switch(*type) {
7079 bpr 92
    case 'a':
93
    case 'w': {
94
        l=strlen(content); fwrite(content,1,l,f); break;
10 reyssat 95
    }
7079 bpr 96
    case 'r': {
97
        l=fread(content,1,MAX_LINELEN-1,f);
98
        if(l>0 && l<MAX_LINELEN) content[l]=0;
99
        else content[0]=0;
100
        break;
101
    }
102
    default: {
103
        content[0]=0; break;
104
    }
105
    }
10 reyssat 106
    fclose(f);
107
}
108
 
8100 bpr 109
/* returns -1 if error */
110
/*
10 reyssat 111
long int filelength(char *fn,...)
112
{
113
    char buf[4096];
114
    va_list vp;
115
    struct stat st;
116
    int l;
7079 bpr 117
 
10 reyssat 118
    va_start(vp,fn);
119
    vsnprintf(buf,sizeof(buf),fn,vp); va_end(vp);
120
    l=stat(buf,&st); if(l) return -1;
121
    return st.st_size;
122
}
8100 bpr 123
*/
7079 bpr 124
    /* recursively generate a directory structure */
8100 bpr 125
void mkdirs2(char *s)
10 reyssat 126
{
127
    struct stat st;
128
    char *buf;
129
    if(stat(s,&st)==-1) {
7079 bpr 130
    if(strrchr(s,'/')!=NULL) {
131
        buf=xmalloc(strlen(s)+1);
132
        ovlstrcpy(buf,s); *strrchr(buf,'/')=0;
8100 bpr 133
        mkdirs2(buf); free(buf);
10 reyssat 134
    }
7079 bpr 135
    mkdir(s,-1);
136
    }
10 reyssat 137
}
138
 
139
void oneline(char *p)
140
{
141
    char tbuf[8], sbuf[8], ubuf[256], cbuf[64];
142
    char *p1, *p2;
143
    int i,t,cl;
144
    memmove(tbuf,p+9,6); tbuf[2]=tbuf[5]=0;
145
    t=atoi(tbuf)*60+atoi(tbuf+3);
146
    memmove(sbuf,p+18,4); sbuf[4]=0;
147
    p1=strchr(p,','); if(p1==NULL) return;
148
    if(!isdigit(*(p1+1))) return;
149
    snprintf(cbuf,sizeof(cbuf),"%s",p1+1);
7079 bpr 150
    for(p2=cbuf;isdigit(*p2); p2++){};
7076 obado 151
    *p2=0; cl=atoi(cbuf);
10 reyssat 152
    *p1=0; for(p1--;p1>p && !isspace(*(p1-1)); p1--);
153
    snprintf(ubuf,sizeof(ubuf),"%s",p1);
154
    for(i=0;i<sescnt;i++) {
7079 bpr 155
    if(cl==ses[i].cl && memcmp(sbuf,ses[i].s,4)==0 &&
156
       ses[i].end>=t-MAX_LAPSE) {
157
        ses[i].end=t; return;
10 reyssat 158
    }
7079 bpr 159
    }
10 reyssat 160
    if(sescnt>=MAX_SESSIONS) return;
161
    memmove(ses[sescnt].s,sbuf,4); ses[sescnt].cl=cl;
162
    ses[sescnt].start=ses[sescnt].end=t;
163
    snprintf(ses[sescnt].u,sizeof(ses[sescnt].u),"%s",ubuf);
164
    sescnt++;
165
}
166
 
167
void onefile(char *fname)
168
{
169
    FILE *f;
170
    long l;
171
    char *fbuf, *p1, *p2, *p3;
172
    l=filelength(fname); if(l<=0) return;
173
    f=fopen(fname,"r"); if(f==NULL) return;
3840 kbelabas 174
    fbuf=xmalloc(l+16); (void)fread(fbuf,1,l,f); fclose(f); fbuf[l]=0;
10 reyssat 175
    for(p1=fbuf; *p1; p1=p2) {
7079 bpr 176
    p2=strchr(p1,'\n'); if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
177
    p3=strchr(p1,','); if(p3==NULL) continue;
178
    if(strncmp(p1,datestr,8)!=0) continue;
179
    oneline(p1);
10 reyssat 180
    }
181
}
182
 
183
void classaccount(void)
184
{
185
    int i,j;
186
    clscnt=0;
187
    for(i=0;i<sescnt;i++) {
7079 bpr 188
    ses[i].cnt=ses[i].end-ses[i].start+MIN_ADD;
189
    if(ses[i].cnt<MIN_CONNECT) ses[i].cnt=MIN_CONNECT;
190
    for(j=0;j<clscnt && ses[i].cl!=cls[j].cl;j++);
191
    if(j<clscnt) cls[j].cnt+=ses[i].cnt;
192
    else if(clscnt<MAX_CLASSES) {
193
        cls[clscnt].cl=ses[i].cl;
194
        cls[clscnt].cnt=ses[i].cnt;
195
        clscnt++;
10 reyssat 196
    }
7079 bpr 197
    }
10 reyssat 198
}
199
 
200
int clscmp(const void *c1, const void *c2)
201
{
202
    struct cls *cl1, *cl2;
203
    cl1=(struct cls *) c1; cl2=(struct cls *) c2;
204
    return cl1->cl-cl2->cl;
205
}
206
 
207
void output(void)
208
{
209
    char *p, buf[1024], dbuf[1024];
210
    int i,t;
211
    p=getenv("ccsum_outdir"); if(p==NULL || *p==0) return;
212
    for(i=0;i<sescnt;i++) {
7079 bpr 213
    snprintf(dbuf,sizeof(dbuf),"%s/%d",p,ses[i].cl);
8100 bpr 214
    mkdirs2(dbuf);
7079 bpr 215
    snprintf(buf,sizeof(buf),"%s.%02d:%02d %d\n",
216
         datestr,ses[i].start/60,ses[i].start%60,ses[i].cnt);
217
    accessfile(buf,"a","%s/%s",dbuf,ses[i].u);
10 reyssat 218
    }
219
    snprintf(dbuf,sizeof(dbuf),"%s/bydate/%.4s",p,datestr);
8100 bpr 220
    mkdirs2(dbuf);
10 reyssat 221
    snprintf(dbuf+strlen(dbuf),sizeof(dbuf)-strlen(dbuf),"/%.2s",datestr+4);
222
    t=0;
223
    qsort(cls,clscnt,sizeof(cls[0]),clscmp);
224
    for(i=0;i<clscnt;i++) {
7079 bpr 225
    snprintf(buf,sizeof(buf),"%s %d\n",datestr,cls[i].cnt);
226
    accessfile(buf,"a","%s/%d/.total",p,cls[i].cl);
227
    snprintf(buf,sizeof(buf),"%s %d %d\n",datestr+4,cls[i].cl,cls[i].cnt);
228
    accessfile(buf,"a","%s",dbuf);
229
    t+=cls[i].cnt;
10 reyssat 230
    }
231
    snprintf(buf,sizeof(buf),"%s %d %d\n",datestr,t,(t+30)/60);
232
    accessfile(buf,"a","%s/done",p);
233
}
234
 
235
int main(int argc, char *argv[])
236
{
237
    sescnt=0;
238
    if(argc<2) return 1;
239
    datestr=getenv("ccsum_date");
240
    if(datestr==NULL || strlen(datestr)!=8) return 2;
241
    onefile(argv[1]);
242
    classaccount();
243
    output();
244
    return 0;
245
}
246