1 #include "global.h"
2
3
4 struct SAentry *Users = NULL;
5 struct SAB3v SAB3variants[6] = {
6 { 999999999999999.0, "P", 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 },
7 { 999999999999.0, "T", 1024.0 * 1024.0 * 1024.0 * 1024.0 },
8 { 999999999.0, "G", 1024.0 * 1024.0 * 1024.0 },
9 { 999999.0, "M", 1024.0 * 1024.0 },
10 { 999.0, "k", 1024.0 },
11 { 0.0, "\000", 1.0 }
12 };
13
14
compSAentryName(const struct SAentry * el1,const struct SAentry * el2)15 int compSAentryName(const struct SAentry *el1, const struct SAentry *el2) {
16 return strcmp(el1->name, el2->name);
17 }
18
19
compSAentryId(const struct SAentry * el1,const struct SAentry * el2)20 int compSAentryId(const struct SAentry *el1, const struct SAentry *el2) {
21 return -SAnumcmp(el1->id, el2->id);
22 }
23
24
rcompSAentryB(const struct SAentry * el1,const struct SAentry * el2)25 int rcompSAentryB(const struct SAentry *el1, const struct SAentry *el2) {
26 return SAnumcmp(el1->U.bytes, el2->U.bytes);
27 }
28
29
compSAusertab(const struct SAusertab * el1,const struct SAusertab * el2)30 int compSAusertab(const struct SAusertab *el1, const struct SAusertab *el2) {
31 return strcmp(el1->iname, el2->iname);
32 }
33
34
compSI(const short int * el1,const short int * el2)35 int compSI(const short int *el1, const short int *el2) {
36 return SAnumcmp(el1[0], el2[0]);
37 }
38
39
SAentryByName(char * sname)40 struct SAentry *SAentryByName(char *sname) {
41 struct SAentry key;
42
43 key.name = sname;
44 return (struct SAentry *)bsearch(&key, Users, (size_t)icfg.ueCount, sizeof(struct SAentry), (int (*)(const void *, const void *))compSAentryName);
45 }
46
47
SAentryById(const int id)48 struct SAentry *SAentryById(const int id) {
49 return &Users[id];
50 }
51
52
LimitedURL(const char * lurl)53 const char *LimitedURL(const char *lurl) {
54 static char retval[URLSIZE];
55 size_t slen, halful;
56
57 if (!cfg.reports_url_limit || (slen = strlen(lurl)) <= (size_t)cfg.reports_url_limit) return lurl;
58
59 halful = (size_t)cfg.reports_url_limit / 2L;
60 SAsnprintf(retval, sizeof(retval), "%.*s...%s", (int)(halful - 2L), lurl, &lurl[slen - halful + 1L]);
61
62 return retval;
63 }
64
65
FixFileName(char * tfname)66 char *FixFileName(char *tfname) {
67 char *t = tfname;
68
69 if (cfg.username_unescape) SAunescape(tfname);
70
71 for (; t[0] != '\0'; t++)
72 if (strchr("/\\?%*:|\"<>();'!$`&", t[0]) != NULL) t[0] = '_';
73 else if (isupper((int)t[0])) t[0] = (char)tolower((int)t[0]);
74
75 if (cfg.username_remove && (t = strstr(tfname, cfg.username_remove))) {
76 if (t == tfname) tfname = t + icfg.username_remove_length;
77 else t[0] = '\0';
78 }
79
80 return tfname;
81 }
82
83
RecipientTolower(char * turl)84 void RecipientTolower(char *turl) {
85 char *t = turl;
86
87 for (; t[0] != '\0'; t++) if (isupper((int)t[0])) t[0] = (char)tolower((int)t[0]);
88 }
89
90
SAB0(double ibytes)91 char *SAB0(double ibytes) {
92 static char retval[32];
93
94 SAsnprintf(retval, sizeof(retval), "%"SATSEP".0f", ibytes);
95
96 return retval;
97 }
98
99
SAB1(double ibytes)100 char *SAB1(double ibytes) {
101 static char retval[32];
102
103 SAsnprintf(retval, sizeof(retval), "%"SATSEP".0f%s", round(ibytes / icfg.reports_bytes_divisor), icfg.locDivisor);
104
105 return retval;
106 }
107
108
SAB2(double ibytes)109 char *SAB2(double ibytes) {
110 static char retval[32];
111
112 SAsnprintf(retval, sizeof(retval), "%"SATSEP".2f%s", ibytes / icfg.reports_bytes_divisor, icfg.locDivisor);
113
114 return retval;
115 }
116
117
SAB3(double ibytes)118 char *SAB3(double ibytes) {
119 static char retval[6];
120 short int i = 0;
121
122 while(i < 5 && ibytes <= SAB3variants[i].vlimit) i++;
123 SAsnprintf(retval, sizeof(retval), "%.0f%s", round(ibytes / SAB3variants[i].divisor), SAB3variants[i].munit);
124
125 return retval;
126 }
127
128
GetDT(time_t idt,const char * fmt)129 char *GetDT(time_t idt, const char *fmt) {
130 static char tdt[DATETIMESIZE];
131
132 if (!strftime(tdt, DATETIMESIZE - 1L, fmt, SAlocaltime(&idt))) SAexit("Can't convert datetime %ld", idt);
133
134 #if DEBUG >= 4
135 SAdebug("%d->%s", idt, tdt);
136 #endif
137
138 return tdt;
139 }
140
141
GetD(struct tm * itm,const char * fmt)142 char *GetD(struct tm *itm, const char *fmt) {
143 static char tdt[DATETIMESIZE];
144
145 if (!strftime(tdt, DATETIMESIZE - 1L, fmt, itm)) SAexit("Can't convert date %d-%d-%d", itm->tm_year, itm->tm_mon, itm->tm_mday);
146
147 #if DEBUG >= 4
148 SAdebug("%d-%d-%d->%s", itm->tm_year, itm->tm_mon, itm->tm_mday, tdt);
149 #endif
150
151 return tdt;
152 }
153
154
GetDZT(const char * idate)155 time_t GetDZT(const char *idate) {
156 struct tm dtconv;
157
158 if (strptime(idate, "%x", &dtconv) == NULL) SAexit("Can't convert date %s", idate);
159 dtconv.tm_sec = dtconv.tm_min = dtconv.tm_hour = 0;
160 dtconv.tm_isdst = -1;
161
162 #if DEBUG >= 4
163 SAdebug("%s->%s", idate, GetDT(SAmktime(&dtconv), "%x %X"));
164 #endif
165
166 return SAmktime(&dtconv);
167 }
168
169
170 /* Compute period and replace specified at CL start/end dates with real ones */
ComputePeriod(time_t rsdate,time_t redate)171 void ComputePeriod(time_t rsdate, time_t redate) {
172 time_t timediff;
173 struct tm *stm, *etm;
174
175
176 if (rsdate > redate) SAexit("Log is seriously corrupted");
177
178 /* Period work, part1: real start date */
179 icfg.SDate = rsdate;
180 stm = SAlocaltime(&icfg.SDate);
181 icfg.SYear = stm->tm_year;
182 SAstrlcpy(icfg.Period, GetDT(icfg.SDate, "%x-"), sizeof(icfg.Period));
183
184 /* Period work, part2: real end date */
185 if (redate < icfg.EDate) icfg.EDate = redate;
186 etm = SAlocaltime(&icfg.EDate);
187 icfg.EYear = etm->tm_year;
188 SAstrlcat(icfg.Period, GetDT(icfg.EDate, "%x"), sizeof(icfg.Period));
189
190 timediff = icfg.EDate - icfg.SDate;
191 if (timediff <= SADAY) icfg.PScale = 24;
192 else if ((timediff <= SAMONTH) || (stm->tm_year == etm->tm_year && stm->tm_mon == etm->tm_mon)) icfg.PScale = 31;
193 else icfg.PScale = 12;
194 }
195
196
197 /* for url relative indicators */
IndicsI(FILE * iFile,short int iIndic)198 void IndicsI(FILE *iFile, short int iIndic) {
199 short int i;
200
201 /* assume that indicators will be writed only to end of table row */
202 for (i = 0; i < icfg.LFcsscount; i++) if (SAgetbit(iIndic, i)) SAfprintf(iFile, "<td class=c%hd>", i);
203 }
204
205
206 /* for user relative indicators */
IndicsByIndexI(FILE * iFile,int i)207 void IndicsByIndexI(FILE *iFile, int i) {
208 short int j;
209
210 /* assume that indicators will be written only to end of table row */
211 for (j = 0; j < icfg.LFcsscount; j++) if (Users[i].LF[j].count) SAfprintf(iFile, "<td class=c%hd>", j);
212 }
213
214
SAunescape(char * istring)215 void SAunescape(char *istring) {
216 size_t slen;
217 char *pstring, *nstring;
218 char hexchar[3] = " \000";
219
220 slen = strlen(istring);
221 nstring = istring;
222
223 for (pstring = istring; pstring != istring + slen + 1L; pstring++) {
224 if (pstring[0] == '%' && SAisxdigit(pstring[1]) && SAisxdigit(pstring[2]) && pstring <= istring + slen - 2L) {
225 hexchar[0] = pstring[1];
226 hexchar[1] = pstring[2];
227
228 nstring++[0] = (char)strtol(hexchar, NULL, 16);
229 pstring += 2;
230 } else nstring++[0] = pstring[0];
231 }
232 }
233
234
FormFnames(struct SAFNAMES * fnames,const char * fmt,...)235 void FormFnames(struct SAFNAMES *fnames, const char *fmt, ...) {
236 va_list args;
237
238 va_start(args, fmt);
239 SAvsnprintf(fnames->srt, sizeof(fnames->srt), fmt, args);
240 SAsnprintf(fnames->uns, sizeof(fnames->srt), "%s.uns", fnames->srt);
241 va_end(args);
242 }
243