1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <config.h>
#include <support.h>
#include <account.h>
struct acclist_s {
struct acclist_s *next;
struct accrec_s rec;
} *accHead;
/*
* ssec <= t <= esec
* ----------+----------+---------
* +---+ (1)
* +---+ (2)
* +---+ (3)
* +---+ (4)
* +---+ (5)
* +---------------+ (6)
*/
time_t
AccountLoad(char *name, time_t ssec, time_t esec, int nmax,
void (*cb)())
{
struct accrec_s rec;
struct acclist_s *acp, *achp=NULL;
struct stat st;
int fd, n=0;
off_t rp;
time_t total=0, dif;
struct _deadlist_s {
struct _deadlist_s *next;
char name[LEN_ACC_NAME];
time_t time;
} *dlp, *dlhp=NULL;
if ((fd = open(_PATH_PPXP_ACC, O_RDONLY)) < 0) return(0);
fstat(fd, &st);
rp = st.st_size;
do {
rp -= sizeof(rec);
if (lseek(fd, rp, SEEK_SET) < 0
|| read(fd, &rec, sizeof(rec)) < 0) break;
if (name && strcmp(rec.name, name)) continue;
dlp = dlhp;
while(dlp) {
if (!strcmp(dlp->name, rec.name)) break;
dlp = dlp->next;
}
if (rec.pid) {
struct acclist_s *acp0=NULL;
bool_t found=FALSE;
if (esec && esec < rec.time.sec) continue;/* (5) */
if (ssec && rec.time.sec < ssec) rec.time.sec = ssec;/* (2,6) */
acp = achp;
while (acp) {
if (acp->rec.aid == rec.aid) {
dif = acp->rec.time.sec - rec.time.sec;
total += dif;
if (cb) cb(&rec, &acp->rec, dif);
if (acp0) acp0->next = acp->next;
else achp = acp->next;
Free(acp);
found = TRUE;
break;
}
acp0 = acp;
acp = acp->next;
}
if (!found) {
if (dlp) dif = (time_t)-1;
else {
time(&dif);
dif -= rec.time.sec;
total += dif;
}
if (cb) cb(&rec, NULL, dif);
}
n ++;
if (nmax && n >= nmax) break;
} else {
if (ssec && rec.time.sec < ssec) break;/* (1) */
if (esec && esec < rec.time.sec)
rec.time.sec = esec;/* (4,6) */
acp = TALLOC(struct acclist_s);
acp->next = achp;
achp = acp;
memcpy(&acp->rec, &rec, sizeof(rec));
if (!dlp) {
dlp = TALLOC(struct _deadlist_s);
dlp->next = dlhp;
dlhp = dlp;
strcpy(dlp->name, rec.name);
}
dlp->time = rec.time.sec;
}
} while (rp > 0);
close(fd);
while (dlhp) {
dlp = dlhp;
dlhp = dlp->next;
Free(dlp);
}
while (achp) {
acp = achp;
achp = acp->next;
Free(acp);
}
return(total);
}
time_t
AccountTotal(char *name, time_t ssec, time_t esec)
{
return(AccountLoad(name, ssec, esec, 0, NULL));
}
|