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 127 128 129
|
/* Distributed Checksum Clearinghouse
*
* build DCC headers
*
* Copyright (c) 2005 by Rhyolite Software
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Rhyolite Software DCC 1.2.74-1.19 $Revision$
*/
#include "dcc_clnt.h"
#include "dcc_xhdr.h"
/* add text to the growing X-DCC-Warning header line */
void
dcc_add_header(DCC_HEADER_BUF *hdr, const char *p, ...)
{
char *hp;
u_int lim, base, n;
va_list args;
lim = sizeof(hdr->buf) - hdr->used;
if (lim <= 4) {
dcc_error_msg("header buffer too small");
return;
}
hp = &hdr->buf[hdr->used];
if (hdr->used > hdr->start_len) {
hp[0] = ' ';
--lim;
base = 1;
} else {
base = 0;
}
va_start(args, p);
n = base + vsnprintf(hp+base, lim-base, p, args);
va_end(args);
if (n >= lim) {
hdr->used += lim;
dcc_error_msg("header buffer too small");
return;
}
hdr->col += n;
/* follow RFC 2822 and limit lines to 78 */
if (hdr->col >= DCC_MAX_HDR_LINE /* if pushed past line end, */
&& hdr->col-n > 8 /* & we didn't start at left margin */
&& base == 1 /* & not the first cksum report */
&& *(hp-1) != ';'
&& lim-n > 1) { /* & there is buffer space */
memmove(hp+1, hp, n+1); /* then break the line */
hp[0] = '\n';
hp[1] = '\t';
hdr->col = n-1+8;
++n;
}
hdr->used += n;
}
int
dcc_xhdr_start(char *xhdr, int xhdr_len)
{
int inx, i;
const char *p;
if (!dcc_clnt_info
|| (inx =
dcc_clnt_info->dcc.act_inx) >= dcc_clnt_info->dcc.num_addrs) {
p = "";
i = 0;
} else {
p = dcc_clnt_info->dcc.addrs[inx].brand;
i = xhdr_len-sizeof(DCC_XHDR_START);
if (i < 0)
i = 0;
if (i > ISZ(DCC_BRAND))
i = ISZ(DCC_BRAND);
}
i = snprintf(xhdr, xhdr_len, DCC_XHDR_START"%.*s-Metrics", i, p);
if (i >= xhdr_len)
i = xhdr_len-1;
return i;
}
void
dcc_header_init(DCC_HEADER_BUF *hdr, DCC_SRVR_ID srvr_id)
{
hdr->used = dcc_xhdr_start(hdr->buf, sizeof(hdr->buf)-8);
hdr->col = hdr->used;
hdr->start_len = hdr->used;
if (srvr_id < DCC_SRVR_ID_MIN || srvr_id > DCC_SRVR_ID_MAX) {
dcc_add_header(hdr, ": %s ??;", dcc_clnt_hostname);
} else {
dcc_add_header(hdr, ": %s %d;", dcc_clnt_hostname, srvr_id);
}
}
/* add a checksum and its counts to a growing X-DCC-Warning header line */
void
dcc_add_header_ck(DCC_HEADER_BUF *hdr,
DCC_CK_TYPES type, /* which kind of checksum */
DCC_TGTS tgts)
{
char tbuf[30], ckcnt[10];
dcc_add_header(hdr, DCC_XHDR_CK_PAT,
dcc_type2str(tbuf, sizeof(tbuf), type, 0, 0),
dcc_cnt2str(ckcnt, sizeof(ckcnt), tgts, 0));
}
|