Subversion Repositories wimsdev

Rev

Rev 7076 | Rev 8100 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7076 Rev 7079
Line 13... Line 13...
13
 *  You should have received a copy of the GNU General Public License
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
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
16
 */
17
 
17
 
18
        /* Computes class connection count (unit: student-minutes) */
18
    /* Computes class connection count (unit: student-minutes) */
19
 
19
 
20
#include "../wimsdef.h"
20
#include "../wimsdef.h"
21
#include "../includes.h"
21
#include "../includes.h"
22
#include "../Lib/basicstr.c"
22
#include "../Lib/basicstr.c"
23
 
23
 
24
        /* The maximal number of sessions within one day */
24
    /* The maximal number of sessions within one day */
25
#define MAX_SESSIONS (128*1024)
25
#define MAX_SESSIONS (128*1024)
26
        /* The maximal number of classes within one day */
26
    /* The maximal number of classes within one day */
27
#define MAX_CLASSES 8192
27
#define MAX_CLASSES 8192
28
        /* At least these minutes will be counted for each session */
28
    /* At least these minutes will be counted for each session */
29
#define MIN_CONNECT 2
29
#define MIN_CONNECT 2
30
        /* Add this number of minutes to each session */
30
    /* Add this number of minutes to each session */
31
#define MIN_ADD 1
31
#define MIN_ADD 1
32
        /* Accounting discontinues after this number of idle minutes */
32
    /* Accounting discontinues after this number of idle minutes */
33
#define MAX_LAPSE 15
33
#define MAX_LAPSE 15
34
 
34
 
35
struct {
35
struct {
36
    char s[4], u[32];
36
    char s[4], u[32];
37
    int cl, start, end, cnt;
37
    int cl, start, end, cnt;
Line 48... Line 48...
48
void *xmalloc(size_t n)
48
void *xmalloc(size_t n)
49
{
49
{
50
    void *p;
50
    void *p;
51
    p=malloc(n);
51
    p=malloc(n);
52
    if(p==NULL) {
52
    if(p==NULL) {
53
        fprintf(stderr,"Malloc failure."); exit(1);
53
    fprintf(stderr,"Malloc failure."); exit(1);
54
    }
54
    }
55
    return p;
55
    return p;
56
}
56
}
57
 
57
 
58
        /* Points to the end of the word */
58
    /* Points to the end of the word */
59
char *find_word_end(char *p)
59
char *find_word_end(char *p)
60
{
60
{
61
    int i;
61
    int i;
62
    for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
62
    for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
63
    return p;
63
    return p;
64
}
64
}
65
 
65
 
66
        /* Strips leading spaces */
66
    /* Strips leading spaces */
67
char *find_word_start(char *p)
67
char *find_word_start(char *p)
68
{
68
{
69
    int i;
69
    int i;
70
    for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
70
    for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
71
    return p;
71
    return p;
72
}
72
}
73
 
73
 
74
        /* Read/write to a file with variable parms to print filename */
74
    /* Read/write to a file with variable parms to print filename */
75
void accessfile(char *content, char *type, char *s,...)
75
void accessfile(char *content, char *type, char *s,...)
76
{
76
{
77
    va_list vp;
77
    va_list vp;
78
    char buf[MAX_LINELEN+1];
78
    char buf[MAX_LINELEN+1];
79
    FILE *f;
79
    FILE *f;
Line 81... Line 81...
81
 
81
 
82
    va_start(vp,s);
82
    va_start(vp,s);
83
    vsnprintf(buf,sizeof(buf),s,vp);
83
    vsnprintf(buf,sizeof(buf),s,vp);
84
    va_end(vp);
84
    va_end(vp);
85
    f=fopen(buf,type); if(f==NULL) {
85
    f=fopen(buf,type); if(f==NULL) {
86
        if(*type=='r') content[0]=0; return;
86
    if(*type=='r') content[0]=0; return;
87
    }
87
    }
88
    switch(*type) {
88
    switch(*type) {
89
        case 'a':
89
    case 'a':
90
        case 'w': {
90
    case 'w': {
91
            l=strlen(content); fwrite(content,1,l,f); break;
91
        l=strlen(content); fwrite(content,1,l,f); break;
92
        }
92
    }
93
        case 'r': {
93
    case 'r': {
94
            l=fread(content,1,MAX_LINELEN-1,f);
94
        l=fread(content,1,MAX_LINELEN-1,f);
95
            if(l>0 && l<MAX_LINELEN) content[l]=0;
95
        if(l>0 && l<MAX_LINELEN) content[l]=0;
96
            else content[0]=0;
96
        else content[0]=0;
97
            break;
97
        break;
98
        }
98
    }
99
        default: {
99
    default: {
100
            content[0]=0; break;
100
        content[0]=0; break;
101
        }
101
    }
102
    }
102
    }
103
    fclose(f);
103
    fclose(f);
104
}
104
}
105
 
105
 
106
        /* returns -1 if error */
106
    /* returns -1 if error */
107
long int filelength(char *fn,...)
107
long int filelength(char *fn,...)
108
{
108
{
109
    char buf[4096];
109
    char buf[4096];
110
    va_list vp;
110
    va_list vp;
111
    struct stat st;
111
    struct stat st;
112
    int l;
112
    int l;
113
   
113
 
114
    va_start(vp,fn);
114
    va_start(vp,fn);
115
    vsnprintf(buf,sizeof(buf),fn,vp); va_end(vp);
115
    vsnprintf(buf,sizeof(buf),fn,vp); va_end(vp);
116
    l=stat(buf,&st); if(l) return -1;
116
    l=stat(buf,&st); if(l) return -1;
117
    return st.st_size;
117
    return st.st_size;
118
}
118
}
119
 
119
 
120
        /* recursively generate a directory structure */
120
    /* recursively generate a directory structure */
121
void mkdirs(char *s)
121
void mkdirs(char *s)
122
{
122
{
123
    struct stat st;
123
    struct stat st;
124
    char *buf;
124
    char *buf;
125
    if(stat(s,&st)==-1) {
125
    if(stat(s,&st)==-1) {
126
        if(strrchr(s,'/')!=NULL) {
126
    if(strrchr(s,'/')!=NULL) {
127
            buf=xmalloc(strlen(s)+1);
127
        buf=xmalloc(strlen(s)+1);
128
            ovlstrcpy(buf,s); *strrchr(buf,'/')=0;
128
        ovlstrcpy(buf,s); *strrchr(buf,'/')=0;
129
            mkdirs(buf); free(buf);
129
        mkdirs(buf); free(buf);
130
        }
130
    }
131
        mkdir(s,-1);
131
    mkdir(s,-1);
132
    }
132
    }
133
}
133
}
134
 
134
 
135
void oneline(char *p)
135
void oneline(char *p)
136
{
136
{
Line 141... Line 141...
141
    t=atoi(tbuf)*60+atoi(tbuf+3);
141
    t=atoi(tbuf)*60+atoi(tbuf+3);
142
    memmove(sbuf,p+18,4); sbuf[4]=0;
142
    memmove(sbuf,p+18,4); sbuf[4]=0;
143
    p1=strchr(p,','); if(p1==NULL) return;
143
    p1=strchr(p,','); if(p1==NULL) return;
144
    if(!isdigit(*(p1+1))) return;
144
    if(!isdigit(*(p1+1))) return;
145
    snprintf(cbuf,sizeof(cbuf),"%s",p1+1);
145
    snprintf(cbuf,sizeof(cbuf),"%s",p1+1);
146
    for(p2=cbuf;isdigit(*p2); p2++);
146
    for(p2=cbuf;isdigit(*p2); p2++){};
147
    *p2=0; cl=atoi(cbuf);
147
    *p2=0; cl=atoi(cbuf);
148
    *p1=0; for(p1--;p1>p && !isspace(*(p1-1)); p1--);
148
    *p1=0; for(p1--;p1>p && !isspace(*(p1-1)); p1--);
149
    snprintf(ubuf,sizeof(ubuf),"%s",p1);
149
    snprintf(ubuf,sizeof(ubuf),"%s",p1);
150
    for(i=0;i<sescnt;i++) {
150
    for(i=0;i<sescnt;i++) {
151
        if(cl==ses[i].cl && memcmp(sbuf,ses[i].s,4)==0 &&
151
    if(cl==ses[i].cl && memcmp(sbuf,ses[i].s,4)==0 &&
152
           ses[i].end>=t-MAX_LAPSE) {
152
       ses[i].end>=t-MAX_LAPSE) {
153
            ses[i].end=t; return;
153
        ses[i].end=t; return;
154
        }
154
    }
155
    }
155
    }
156
    if(sescnt>=MAX_SESSIONS) return;
156
    if(sescnt>=MAX_SESSIONS) return;
157
    memmove(ses[sescnt].s,sbuf,4); ses[sescnt].cl=cl;
157
    memmove(ses[sescnt].s,sbuf,4); ses[sescnt].cl=cl;
158
    ses[sescnt].start=ses[sescnt].end=t;
158
    ses[sescnt].start=ses[sescnt].end=t;
159
    snprintf(ses[sescnt].u,sizeof(ses[sescnt].u),"%s",ubuf);
159
    snprintf(ses[sescnt].u,sizeof(ses[sescnt].u),"%s",ubuf);
Line 167... Line 167...
167
    char *fbuf, *p1, *p2, *p3;
167
    char *fbuf, *p1, *p2, *p3;
168
    l=filelength(fname); if(l<=0) return;
168
    l=filelength(fname); if(l<=0) return;
169
    f=fopen(fname,"r"); if(f==NULL) return;
169
    f=fopen(fname,"r"); if(f==NULL) return;
170
    fbuf=xmalloc(l+16); (void)fread(fbuf,1,l,f); fclose(f); fbuf[l]=0;
170
    fbuf=xmalloc(l+16); (void)fread(fbuf,1,l,f); fclose(f); fbuf[l]=0;
171
    for(p1=fbuf; *p1; p1=p2) {
171
    for(p1=fbuf; *p1; p1=p2) {
172
        p2=strchr(p1,'\n'); if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
172
    p2=strchr(p1,'\n'); if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
173
        p3=strchr(p1,','); if(p3==NULL) continue;
173
    p3=strchr(p1,','); if(p3==NULL) continue;
174
        if(strncmp(p1,datestr,8)!=0) continue;
174
    if(strncmp(p1,datestr,8)!=0) continue;
175
        oneline(p1);
175
    oneline(p1);
176
    }
176
    }
177
}
177
}
178
 
178
 
179
void classaccount(void)
179
void classaccount(void)
180
{
180
{
181
    int i,j;
181
    int i,j;
182
    clscnt=0;
182
    clscnt=0;
183
    for(i=0;i<sescnt;i++) {
183
    for(i=0;i<sescnt;i++) {
184
        ses[i].cnt=ses[i].end-ses[i].start+MIN_ADD;
184
    ses[i].cnt=ses[i].end-ses[i].start+MIN_ADD;
185
        if(ses[i].cnt<MIN_CONNECT) ses[i].cnt=MIN_CONNECT;
185
    if(ses[i].cnt<MIN_CONNECT) ses[i].cnt=MIN_CONNECT;
186
        for(j=0;j<clscnt && ses[i].cl!=cls[j].cl;j++);
186
    for(j=0;j<clscnt && ses[i].cl!=cls[j].cl;j++);
187
        if(j<clscnt) cls[j].cnt+=ses[i].cnt;
187
    if(j<clscnt) cls[j].cnt+=ses[i].cnt;
188
        else if(clscnt<MAX_CLASSES) {
188
    else if(clscnt<MAX_CLASSES) {
189
            cls[clscnt].cl=ses[i].cl;
189
        cls[clscnt].cl=ses[i].cl;
190
            cls[clscnt].cnt=ses[i].cnt;
190
        cls[clscnt].cnt=ses[i].cnt;
191
            clscnt++;
191
        clscnt++;
192
        }
192
    }
193
    }
193
    }
194
}
194
}
195
 
195
 
196
int clscmp(const void *c1, const void *c2)
196
int clscmp(const void *c1, const void *c2)
197
{
197
{
Line 204... Line 204...
204
{
204
{
205
    char *p, buf[1024], dbuf[1024];
205
    char *p, buf[1024], dbuf[1024];
206
    int i,t;
206
    int i,t;
207
    p=getenv("ccsum_outdir"); if(p==NULL || *p==0) return;
207
    p=getenv("ccsum_outdir"); if(p==NULL || *p==0) return;
208
    for(i=0;i<sescnt;i++) {
208
    for(i=0;i<sescnt;i++) {
209
        snprintf(dbuf,sizeof(dbuf),"%s/%d",p,ses[i].cl);
209
    snprintf(dbuf,sizeof(dbuf),"%s/%d",p,ses[i].cl);
210
        mkdirs(dbuf);
210
    mkdirs(dbuf);
211
        snprintf(buf,sizeof(buf),"%s.%02d:%02d %d\n",
211
    snprintf(buf,sizeof(buf),"%s.%02d:%02d %d\n",
212
                 datestr,ses[i].start/60,ses[i].start%60,ses[i].cnt);
212
         datestr,ses[i].start/60,ses[i].start%60,ses[i].cnt);
213
        accessfile(buf,"a","%s/%s",dbuf,ses[i].u);
213
    accessfile(buf,"a","%s/%s",dbuf,ses[i].u);
214
    }
214
    }
215
    snprintf(dbuf,sizeof(dbuf),"%s/bydate/%.4s",p,datestr);
215
    snprintf(dbuf,sizeof(dbuf),"%s/bydate/%.4s",p,datestr);
216
    mkdirs(dbuf);
216
    mkdirs(dbuf);
217
    snprintf(dbuf+strlen(dbuf),sizeof(dbuf)-strlen(dbuf),"/%.2s",datestr+4);
217
    snprintf(dbuf+strlen(dbuf),sizeof(dbuf)-strlen(dbuf),"/%.2s",datestr+4);
218
    t=0;
218
    t=0;
219
    qsort(cls,clscnt,sizeof(cls[0]),clscmp);
219
    qsort(cls,clscnt,sizeof(cls[0]),clscmp);
220
    for(i=0;i<clscnt;i++) {
220
    for(i=0;i<clscnt;i++) {
221
        snprintf(buf,sizeof(buf),"%s %d\n",datestr,cls[i].cnt);
221
    snprintf(buf,sizeof(buf),"%s %d\n",datestr,cls[i].cnt);
222
        accessfile(buf,"a","%s/%d/.total",p,cls[i].cl);
222
    accessfile(buf,"a","%s/%d/.total",p,cls[i].cl);
223
        snprintf(buf,sizeof(buf),"%s %d %d\n",datestr+4,cls[i].cl,cls[i].cnt);
223
    snprintf(buf,sizeof(buf),"%s %d %d\n",datestr+4,cls[i].cl,cls[i].cnt);
224
        accessfile(buf,"a","%s",dbuf);
224
    accessfile(buf,"a","%s",dbuf);
225
        t+=cls[i].cnt;
225
    t+=cls[i].cnt;
226
    }
226
    }
227
    snprintf(buf,sizeof(buf),"%s %d %d\n",datestr,t,(t+30)/60);
227
    snprintf(buf,sizeof(buf),"%s %d %d\n",datestr,t,(t+30)/60);
228
    accessfile(buf,"a","%s/done",p);
228
    accessfile(buf,"a","%s/done",p);
229
}
229
}
230
 
230