| | varnish-cache/lib/libvarnishapi/vsl.c |
| 0 |
|
/*- |
| 1 |
|
* Copyright (c) 2006 Verdens Gang AS |
| 2 |
|
* Copyright (c) 2006-2015 Varnish Software AS |
| 3 |
|
* All rights reserved. |
| 4 |
|
* |
| 5 |
|
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk> |
| 6 |
|
* Author: Martin Blix Grydeland <martin@varnish-software.com> |
| 7 |
|
* |
| 8 |
|
* SPDX-License-Identifier: BSD-2-Clause |
| 9 |
|
* |
| 10 |
|
* Redistribution and use in source and binary forms, with or without |
| 11 |
|
* modification, are permitted provided that the following conditions |
| 12 |
|
* are met: |
| 13 |
|
* 1. Redistributions of source code must retain the above copyright |
| 14 |
|
* notice, this list of conditions and the following disclaimer. |
| 15 |
|
* 2. Redistributions in binary form must reproduce the above copyright |
| 16 |
|
* notice, this list of conditions and the following disclaimer in the |
| 17 |
|
* documentation and/or other materials provided with the distribution. |
| 18 |
|
* |
| 19 |
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 20 |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 |
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE |
| 23 |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 24 |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 25 |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 26 |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 27 |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 28 |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 29 |
|
* SUCH DAMAGE. |
| 30 |
|
*/ |
| 31 |
|
|
| 32 |
|
#include "config.h" |
| 33 |
|
|
| 34 |
|
#include <stdarg.h> |
| 35 |
|
#include <stdint.h> |
| 36 |
|
#include <stdio.h> |
| 37 |
|
|
| 38 |
|
#include "vdef.h" |
| 39 |
|
#include "vas.h" |
| 40 |
|
#include "miniobj.h" |
| 41 |
|
|
| 42 |
|
#include "vbm.h" |
| 43 |
|
#include "vqueue.h" |
| 44 |
|
#include "vre.h" |
| 45 |
|
#include "vsb.h" |
| 46 |
|
|
| 47 |
|
#include "vapi/vsl.h" |
| 48 |
|
|
| 49 |
|
#include "vsl_api.h" |
| 50 |
|
|
| 51 |
|
/*--------------------------------------------------------------------*/ |
| 52 |
|
|
| 53 |
|
const char vsl_file_id[] = {'V', 'S', 'L', '2'}; |
| 54 |
|
|
| 55 |
|
const char * const VSL_tags[SLT__MAX] = { |
| 56 |
|
# define SLTM(foo,flags,sdesc,ldesc) [SLT_##foo] = #foo, |
| 57 |
|
# include "tbl/vsl_tags.h" |
| 58 |
|
}; |
| 59 |
|
|
| 60 |
|
const unsigned VSL_tagflags[SLT__MAX] = { |
| 61 |
|
# define SLTM(foo, flags, sdesc, ldesc) [SLT_##foo] = flags, |
| 62 |
|
# include "tbl/vsl_tags.h" |
| 63 |
|
# undef SLTM |
| 64 |
|
}; |
| 65 |
|
|
| 66 |
|
int |
| 67 |
192397 |
vsl_diag(struct VSL_data *vsl, const char *fmt, ...) |
| 68 |
|
{ |
| 69 |
|
va_list ap; |
| 70 |
|
|
| 71 |
192397 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 72 |
192397 |
AN(fmt); |
| 73 |
|
|
| 74 |
192397 |
if (vsl->diag == NULL) |
| 75 |
192397 |
vsl->diag = VSB_new_auto(); |
| 76 |
192397 |
AN(vsl->diag); |
| 77 |
192397 |
VSB_clear(vsl->diag); |
| 78 |
192397 |
va_start(ap, fmt); |
| 79 |
192397 |
VSB_vprintf(vsl->diag, fmt, ap); |
| 80 |
192397 |
va_end(ap); |
| 81 |
192397 |
AZ(VSB_finish(vsl->diag)); |
| 82 |
192397 |
return (-1); |
| 83 |
|
} |
| 84 |
|
|
| 85 |
|
struct VSL_data * |
| 86 |
56556 |
VSL_New(void) |
| 87 |
|
{ |
| 88 |
|
struct VSL_data *vsl; |
| 89 |
|
|
| 90 |
56556 |
ALLOC_OBJ(vsl, VSL_MAGIC); |
| 91 |
56556 |
if (vsl == NULL) |
| 92 |
0 |
return (NULL); |
| 93 |
|
|
| 94 |
56556 |
vsl->L_opt = 1000; |
| 95 |
56556 |
vsl->T_opt = 120.; |
| 96 |
56556 |
vsl->vbm_select = vbit_new(SLT__MAX); |
| 97 |
56556 |
vsl->vbm_suppress = vbit_new(SLT__MAX); |
| 98 |
56556 |
VTAILQ_INIT(&vsl->vslf_select); |
| 99 |
56556 |
VTAILQ_INIT(&vsl->vslf_suppress); |
| 100 |
|
|
| 101 |
56556 |
return (vsl); |
| 102 |
56556 |
} |
| 103 |
|
|
| 104 |
|
static void |
| 105 |
101672 |
vsl_IX_free(vslf_list *filters) |
| 106 |
|
{ |
| 107 |
|
struct vslf *vslf; |
| 108 |
|
|
| 109 |
101832 |
while (!VTAILQ_EMPTY(filters)) { |
| 110 |
160 |
vslf = VTAILQ_FIRST(filters); |
| 111 |
160 |
CHECK_OBJ_NOTNULL(vslf, VSLF_MAGIC); |
| 112 |
160 |
VTAILQ_REMOVE(filters, vslf, list); |
| 113 |
160 |
if (vslf->tags) |
| 114 |
0 |
vbit_destroy(vslf->tags); |
| 115 |
160 |
AN(vslf->vre); |
| 116 |
160 |
VRE_free(&vslf->vre); |
| 117 |
160 |
AZ(vslf->vre); |
| 118 |
160 |
FREE_OBJ(vslf); |
| 119 |
|
} |
| 120 |
101672 |
} |
| 121 |
|
|
| 122 |
|
void |
| 123 |
50836 |
VSL_Delete(struct VSL_data *vsl) |
| 124 |
|
{ |
| 125 |
|
|
| 126 |
50836 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 127 |
|
|
| 128 |
50836 |
vbit_destroy(vsl->vbm_select); |
| 129 |
50836 |
vbit_destroy(vsl->vbm_suppress); |
| 130 |
50836 |
vsl_IX_free(&vsl->vslf_select); |
| 131 |
50836 |
vsl_IX_free(&vsl->vslf_suppress); |
| 132 |
50836 |
VSL_ResetError(vsl); |
| 133 |
50836 |
FREE_OBJ(vsl); |
| 134 |
50836 |
} |
| 135 |
|
|
| 136 |
|
const char * |
| 137 |
192397 |
VSL_Error(const struct VSL_data *vsl) |
| 138 |
|
{ |
| 139 |
|
|
| 140 |
192397 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 141 |
|
|
| 142 |
192397 |
if (vsl->diag == NULL) |
| 143 |
0 |
return (NULL); |
| 144 |
|
else |
| 145 |
192397 |
return (VSB_data(vsl->diag)); |
| 146 |
192397 |
} |
| 147 |
|
|
| 148 |
|
void |
| 149 |
241113 |
VSL_ResetError(struct VSL_data *vsl) |
| 150 |
|
{ |
| 151 |
|
|
| 152 |
241113 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 153 |
|
|
| 154 |
241113 |
if (vsl->diag == NULL) |
| 155 |
50836 |
return; |
| 156 |
190277 |
VSB_destroy(&vsl->diag); |
| 157 |
241113 |
} |
| 158 |
|
|
| 159 |
|
static int |
| 160 |
2080 |
vsl_match_IX(struct VSL_data *vsl, const vslf_list *list, |
| 161 |
|
const struct VSL_cursor *c) |
| 162 |
|
{ |
| 163 |
|
enum VSL_tag_e tag; |
| 164 |
|
const char *cdata; |
| 165 |
|
int len; |
| 166 |
|
const struct vslf *vslf; |
| 167 |
|
|
| 168 |
2080 |
(void)vsl; |
| 169 |
2080 |
tag = VSL_TAG(c->rec.ptr); |
| 170 |
2080 |
cdata = VSL_CDATA(c->rec.ptr); |
| 171 |
2080 |
len = VSL_LEN(c->rec.ptr); |
| 172 |
|
|
| 173 |
3600 |
VTAILQ_FOREACH(vslf, list, list) { |
| 174 |
2080 |
CHECK_OBJ_NOTNULL(vslf, VSLF_MAGIC); |
| 175 |
2080 |
if (vslf->tags != NULL && !vbit_test(vslf->tags, tag)) |
| 176 |
0 |
continue; |
| 177 |
2080 |
if (VRE_match(vslf->vre, cdata, len, 0, NULL) >= 0) |
| 178 |
560 |
return (1); |
| 179 |
1520 |
} |
| 180 |
1520 |
return (0); |
| 181 |
2080 |
} |
| 182 |
|
|
| 183 |
|
int |
| 184 |
1305458 |
VSL_Match(struct VSL_data *vsl, const struct VSL_cursor *c) |
| 185 |
|
{ |
| 186 |
|
enum VSL_tag_e tag; |
| 187 |
|
|
| 188 |
1305458 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 189 |
1305458 |
if (c == NULL || c->rec.ptr == NULL) |
| 190 |
60 |
return (0); |
| 191 |
1305456 |
tag = VSL_TAG(c->rec.ptr); |
| 192 |
1305456 |
if (tag <= SLT__Bogus || tag >= SLT__Reserved) |
| 193 |
42 |
return (0); |
| 194 |
1305430 |
if (!vsl->c_opt || !vsl->b_opt) { |
| 195 |
1304080 |
if (vsl->c_opt && !VSL_CLIENT(c->rec.ptr)) |
| 196 |
3920 |
return (0); |
| 197 |
1300160 |
if (vsl->b_opt && !VSL_BACKEND(c->rec.ptr)) |
| 198 |
0 |
return (0); |
| 199 |
1300160 |
} |
| 200 |
1301510 |
if (!VTAILQ_EMPTY(&vsl->vslf_select) && |
| 201 |
240 |
vsl_match_IX(vsl, &vsl->vslf_select, c)) |
| 202 |
80 |
return (1); |
| 203 |
1301430 |
else if (vbit_test(vsl->vbm_select, tag)) |
| 204 |
0 |
return (1); |
| 205 |
1301430 |
else if (!VTAILQ_EMPTY(&vsl->vslf_suppress) && |
| 206 |
1840 |
vsl_match_IX(vsl, &vsl->vslf_suppress, c)) |
| 207 |
480 |
return (0); |
| 208 |
1300950 |
else if (vbit_test(vsl->vbm_suppress, tag)) |
| 209 |
65400 |
return (0); |
| 210 |
|
|
| 211 |
|
/* Default show */ |
| 212 |
1235550 |
return (1); |
| 213 |
1305430 |
} |
| 214 |
|
|
| 215 |
|
static const char * const VSL_transactions[VSL_t__MAX] = { |
| 216 |
|
/* 12345678901234 */ |
| 217 |
|
[VSL_t_unknown] = "<< Unknown >>", |
| 218 |
|
[VSL_t_sess] = "<< Session >>", |
| 219 |
|
[VSL_t_req] = "<< Request >>", |
| 220 |
|
[VSL_t_bereq] = "<< BeReq >>", |
| 221 |
|
[VSL_t_raw] = "<< Record >>", |
| 222 |
|
}; |
| 223 |
|
|
| 224 |
|
#define VSL_PRINT(...) \ |
| 225 |
|
do { \ |
| 226 |
|
if (0 > fprintf(__VA_ARGS__)) \ |
| 227 |
|
return (-5); \ |
| 228 |
|
} while (0) |
| 229 |
|
|
| 230 |
|
static int |
| 231 |
3209 |
vsl_print_unsafe(FILE *fo, unsigned len, const char *data) |
| 232 |
|
{ |
| 233 |
|
|
| 234 |
3209 |
VSL_PRINT(fo, "\""); |
| 235 |
197451 |
while (len-- > 0) { |
| 236 |
194242 |
if (*data >= ' ' && *data <= '~') |
| 237 |
191033 |
VSL_PRINT(fo, "%c", *data); |
| 238 |
|
else |
| 239 |
3209 |
VSL_PRINT(fo, "%%%02x", (unsigned char)*data); |
| 240 |
194242 |
data++; |
| 241 |
|
} |
| 242 |
3209 |
VSL_PRINT(fo, "\"\n"); |
| 243 |
3209 |
return (0); |
| 244 |
3209 |
} |
| 245 |
|
|
| 246 |
|
|
| 247 |
|
static int |
| 248 |
892 |
vsl_print_binary(FILE *fo, unsigned len, const char *data) |
| 249 |
|
{ |
| 250 |
|
|
| 251 |
892 |
VSL_PRINT(fo, "["); |
| 252 |
20702 |
while (len-- > 0) { |
| 253 |
19810 |
VSL_PRINT(fo, "%02x", (unsigned char)*data); |
| 254 |
19810 |
data++; |
| 255 |
|
} |
| 256 |
892 |
VSL_PRINT(fo, "]\n"); |
| 257 |
892 |
return (0); |
| 258 |
892 |
} |
| 259 |
|
|
| 260 |
|
static int |
| 261 |
22696 |
vsl_print(const struct VSL_data *vsl, const struct VSL_cursor *c, void *fo, |
| 262 |
|
int terse) |
| 263 |
|
{ |
| 264 |
|
enum VSL_tag_e tag; |
| 265 |
|
uint64_t vxid; |
| 266 |
|
unsigned len; |
| 267 |
|
const char *data; |
| 268 |
|
int type; |
| 269 |
|
|
| 270 |
22696 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 271 |
22696 |
if (c == NULL || c->rec.ptr == NULL) |
| 272 |
0 |
return (0); |
| 273 |
22696 |
if (fo == NULL) |
| 274 |
0 |
fo = stdout; |
| 275 |
22696 |
tag = VSL_TAG(c->rec.ptr); |
| 276 |
22696 |
vxid = VSL_ID(c->rec.ptr); |
| 277 |
22696 |
len = VSL_LEN(c->rec.ptr); |
| 278 |
22696 |
type = VSL_CLIENT(c->rec.ptr) ? 'c' : VSL_BACKEND(c->rec.ptr) ? |
| 279 |
|
'b' : '-'; |
| 280 |
22696 |
data = VSL_CDATA(c->rec.ptr); |
| 281 |
|
|
| 282 |
22696 |
if (!terse) |
| 283 |
18176 |
VSL_PRINT(fo, "%10ju ", (uintmax_t)vxid); |
| 284 |
22696 |
VSL_PRINT(fo, "%-14s ", VSL_tags[tag]); |
| 285 |
22696 |
if (!terse) |
| 286 |
18176 |
VSL_PRINT(fo, "%c ", type); |
| 287 |
|
|
| 288 |
22696 |
if (VSL_tagflags[tag] & SLT_F_UNSAFE) |
| 289 |
3209 |
(void)vsl_print_unsafe(fo, len, data); |
| 290 |
19487 |
else if (VSL_tagflags[tag] & SLT_F_BINARY) |
| 291 |
892 |
(void)vsl_print_binary(fo, len, data); |
| 292 |
|
else |
| 293 |
18595 |
VSL_PRINT(fo, "%.*s\n", (int)len, data); |
| 294 |
|
|
| 295 |
22696 |
return (0); |
| 296 |
22696 |
} |
| 297 |
|
|
| 298 |
|
int |
| 299 |
18176 |
VSL_Print(const struct VSL_data *vsl, const struct VSL_cursor *c, void *fo) |
| 300 |
|
{ |
| 301 |
|
|
| 302 |
18176 |
return (vsl_print(vsl, c, fo, 0)); |
| 303 |
|
} |
| 304 |
|
|
| 305 |
|
int |
| 306 |
4520 |
VSL_PrintTerse(const struct VSL_data *vsl, const struct VSL_cursor *c, void *fo) |
| 307 |
|
{ |
| 308 |
|
|
| 309 |
4520 |
return (vsl_print(vsl, c, fo, 1)); |
| 310 |
|
} |
| 311 |
|
|
| 312 |
|
int |
| 313 |
0 |
VSL_PrintAll(struct VSL_data *vsl, const struct VSL_cursor *c, void *fo) |
| 314 |
|
{ |
| 315 |
|
int i; |
| 316 |
|
|
| 317 |
0 |
if (c == NULL) |
| 318 |
0 |
return (0); |
| 319 |
0 |
while (1) { |
| 320 |
0 |
i = VSL_Next(c); |
| 321 |
0 |
if (i <= 0) |
| 322 |
0 |
return (i); |
| 323 |
0 |
if (!VSL_Match(vsl, c)) |
| 324 |
0 |
continue; |
| 325 |
0 |
i = VSL_Print(vsl, c, fo); |
| 326 |
0 |
if (i != 0) |
| 327 |
0 |
return (i); |
| 328 |
|
} |
| 329 |
0 |
} |
| 330 |
|
|
| 331 |
|
int v_matchproto_(VSLQ_dispatch_f) |
| 332 |
33136 |
VSL_PrintTransactions(struct VSL_data *vsl, struct VSL_transaction * const pt[], |
| 333 |
|
void *fo) |
| 334 |
|
{ |
| 335 |
|
struct VSL_transaction *t; |
| 336 |
|
int i; |
| 337 |
33136 |
int delim = 0; |
| 338 |
|
int verbose; |
| 339 |
|
|
| 340 |
33136 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 341 |
33136 |
if (fo == NULL) |
| 342 |
27306 |
fo = stdout; |
| 343 |
33136 |
if (pt[0] == NULL) |
| 344 |
0 |
return (0); |
| 345 |
|
|
| 346 |
66512 |
for (t = pt[0]; t != NULL; t = *++pt) { |
| 347 |
33376 |
if (vsl->c_opt || vsl->b_opt) { |
| 348 |
14760 |
switch (t->type) { |
| 349 |
|
case VSL_t_req: |
| 350 |
800 |
if (!vsl->c_opt) |
| 351 |
0 |
continue; |
| 352 |
800 |
if (t->reason == VSL_r_esi && !vsl->E_opt) |
| 353 |
160 |
continue; |
| 354 |
640 |
break; |
| 355 |
|
case VSL_t_bereq: |
| 356 |
160 |
if (!vsl->b_opt) |
| 357 |
80 |
continue; |
| 358 |
80 |
break; |
| 359 |
|
case VSL_t_raw: |
| 360 |
13680 |
break; |
| 361 |
|
default: |
| 362 |
120 |
continue; |
| 363 |
|
} |
| 364 |
14400 |
} |
| 365 |
|
|
| 366 |
33016 |
verbose = 0; |
| 367 |
33016 |
if (t->level == 0 || vsl->v_opt) |
| 368 |
32056 |
verbose = 1; |
| 369 |
|
|
| 370 |
33016 |
if (t->level) { |
| 371 |
|
/* Print header */ |
| 372 |
1000 |
if (t->level > 3) |
| 373 |
0 |
VSL_PRINT(fo, "*%1.1d* ", t->level); |
| 374 |
|
else |
| 375 |
1000 |
VSL_PRINT(fo, "%-3.*s ", |
| 376 |
|
(int)(t->level), "***"); |
| 377 |
1000 |
VSL_PRINT(fo, "%*.s%-14s %*.s%-10ju\n", |
| 378 |
|
verbose ? 10 + 1 : 0, " ", |
| 379 |
|
VSL_transactions[t->type], |
| 380 |
|
verbose ? 1 + 1 : 0, " ", |
| 381 |
|
(uintmax_t)t->vxid); |
| 382 |
1000 |
delim = 1; |
| 383 |
1000 |
} |
| 384 |
|
|
| 385 |
55712 |
while (1) { |
| 386 |
|
/* Print records */ |
| 387 |
94672 |
i = VSL_Next(t->c); |
| 388 |
94672 |
if (i < 0) |
| 389 |
0 |
return (i); |
| 390 |
94672 |
if (i == 0) |
| 391 |
33016 |
break; |
| 392 |
61656 |
if (!VSL_Match(vsl, t->c)) |
| 393 |
38960 |
continue; |
| 394 |
22696 |
if (t->level > 3) |
| 395 |
0 |
VSL_PRINT(fo, "-%1.1d- ", t->level); |
| 396 |
22696 |
else if (t->level) |
| 397 |
4560 |
VSL_PRINT(fo, "%-3.*s ", |
| 398 |
|
(int)(t->level), "---"); |
| 399 |
22696 |
if (verbose) |
| 400 |
18176 |
i = VSL_Print(vsl, t->c, fo); |
| 401 |
|
else |
| 402 |
4520 |
i = VSL_PrintTerse(vsl, t->c, fo); |
| 403 |
22696 |
if (i != 0) |
| 404 |
0 |
return (i); |
| 405 |
|
} |
| 406 |
33016 |
} |
| 407 |
|
|
| 408 |
33136 |
if (delim) |
| 409 |
1000 |
VSL_PRINT(fo, "\n");; |
| 410 |
|
|
| 411 |
33136 |
return (0); |
| 412 |
33136 |
} |
| 413 |
|
|
| 414 |
|
FILE* |
| 415 |
160 |
VSL_WriteOpen(struct VSL_data *vsl, const char *name, int append, int unbuf) |
| 416 |
|
{ |
| 417 |
|
FILE* f; |
| 418 |
|
|
| 419 |
160 |
if (!strcmp(name, "-")) |
| 420 |
40 |
f = stdout; |
| 421 |
|
else |
| 422 |
120 |
f = fopen(name, append ? "a" : "w"); |
| 423 |
160 |
if (f == NULL) { |
| 424 |
40 |
vsl_diag(vsl, "%s", strerror(errno)); |
| 425 |
40 |
return (NULL); |
| 426 |
|
} |
| 427 |
120 |
if (unbuf) |
| 428 |
0 |
setbuf(f, NULL); |
| 429 |
120 |
if (ftell(f) == 0 || f == stdout) { |
| 430 |
120 |
if (fwrite(VSL_FILE_ID, 1, sizeof VSL_FILE_ID, f) != |
| 431 |
|
sizeof VSL_FILE_ID) { |
| 432 |
0 |
vsl_diag(vsl, "%s", strerror(errno)); |
| 433 |
0 |
(void)fclose(f); |
| 434 |
0 |
return (NULL); |
| 435 |
|
} |
| 436 |
120 |
} |
| 437 |
120 |
return (f); |
| 438 |
160 |
} |
| 439 |
|
|
| 440 |
|
int |
| 441 |
4280 |
VSL_Write(const struct VSL_data *vsl, const struct VSL_cursor *c, void *fo) |
| 442 |
|
{ |
| 443 |
|
size_t r; |
| 444 |
|
|
| 445 |
4280 |
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC); |
| 446 |
4280 |
if (c == NULL || c->rec.ptr == NULL) |
| 447 |
0 |
return (0); |
| 448 |
4280 |
if (fo == NULL) |
| 449 |
0 |
fo = stdout; |
| 450 |
8560 |
r = fwrite(c->rec.ptr, sizeof *c->rec.ptr, |
| 451 |
4280 |
VSL_NEXT(c->rec.ptr) - c->rec.ptr, fo); |
| 452 |
4280 |
if (r == 0) |
| 453 |
0 |
return (-5); |
| 454 |
4280 |
return (0); |
| 455 |
4280 |
} |
| 456 |
|
|
| 457 |
|
int |
| 458 |
360 |
VSL_WriteAll(struct VSL_data *vsl, const struct VSL_cursor *c, void *fo) |
| 459 |
|
{ |
| 460 |
|
int i; |
| 461 |
|
|
| 462 |
360 |
if (c == NULL) |
| 463 |
0 |
return (0); |
| 464 |
4640 |
while (1) { |
| 465 |
10960 |
i = VSL_Next(c); |
| 466 |
10960 |
if (i <= 0) |
| 467 |
360 |
return (i); |
| 468 |
10600 |
if (!VSL_Match(vsl, c)) |
| 469 |
6320 |
continue; |
| 470 |
4280 |
i = VSL_Write(vsl, c, fo); |
| 471 |
4280 |
if (i != 0) |
| 472 |
0 |
return (i); |
| 473 |
|
} |
| 474 |
360 |
} |
| 475 |
|
|
| 476 |
|
int v_matchproto_(VSLQ_dispatch_f) |
| 477 |
360 |
VSL_WriteTransactions(struct VSL_data *vsl, struct VSL_transaction * const pt[], |
| 478 |
|
void *fo) |
| 479 |
|
{ |
| 480 |
|
struct VSL_transaction *t; |
| 481 |
|
int i; |
| 482 |
|
|
| 483 |
360 |
if (pt == NULL) |
| 484 |
0 |
return (0); |
| 485 |
720 |
for (i = 0, t = pt[0]; i == 0 && t != NULL; t = *++pt) |
| 486 |
360 |
i = VSL_WriteAll(vsl, t->c, fo); |
| 487 |
360 |
return (i); |
| 488 |
360 |
} |