Logo Search packages:      
Sourcecode: dcc version File versions  Download package

header.c

/* 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));
}

Generated by  Doxygen 1.6.0   Back to index