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

format.cc

/*
 *    tardy - a tar post-processor
 *    Copyright (C) 1998, 1999, 2001, 2002 Peter Miller;
 *    All rights reserved.
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 *
 * MANIFEST: functions to manipulate formats
 */

#include <ac/errno.h>
#include <ac/string.h>

#include <tar/format.h>


static long
octal(char *buf, long len)
{
      long  value;

      errno = EINVAL;
      value = 0;
      while (len > 0 && *buf == ' ')
      {
            ++buf;
            --len;
      }
      if (len <= 0)
            return -1;
      while (len > 0)
      {
            if (!*buf || *buf == ' ')
                  break;
            if (*buf < '0' || *buf > '7')
                  return -1;
            /*
             * Limit the range to 0..2^31-1.
             * Must test for overflow *before* the shift.
             */
            if (value & 0xF0000000)
            {
                  errno = ERANGE;
                  return -1;
            }

            value = (value << 3) + (*buf++ & 7);
            --len;
      }
      errno = 0;
      return value;
}


static void
to_octal(char *buf, long len, long n)
{
      buf[--len] = 0;
      memset(buf, ' ', len);
      while (len > 0)
      {
            buf[--len] = '0' + (n & 7);
            n >>= 3;
            if (!n)
                  break;
      }
}


static size_t
strnlen(char *s, size_t n)
{
      char  *ss = s;

      while (n > 0 && *s)
      {
            ++s;
            --n;
      }
      return (s - ss);
}


static void
string_field_set(char *to_buf, int to_len, const rcstring &from)
{
      int from_len = from.length();
      const char *from_buf = from.to_c_string();
      if (from_len > to_len - 1)
            from_len = to_len - 1;
      if (from_len)
            memcpy(to_buf, from_buf, from_len);
      if (from_len < to_len)
            memset(to_buf + from_len, 0, to_len - from_len);
}


rcstring
header_ty::name_get()
{
      return rcstring(name, strnlen(name, sizeof(name)));
}


void
header_ty::name_set(const rcstring &arg)
{
      string_field_set(name, sizeof(name), arg);
}


long
header_ty::mode_get()
{
      return (07777 & octal(mode, sizeof(mode)));
}


void
header_ty::mode_set(long n)
{
      to_octal(mode, sizeof(mode), n);
}


long
header_ty::uid_get()
{
      return octal(uid, sizeof(uid));
}


void
header_ty::uid_set(long n)
{
      to_octal(uid, sizeof(uid), n);
}


long
header_ty::gid_get()
{
      return octal(gid, sizeof(gid));
}


void
header_ty::gid_set(long n)
{
      to_octal(gid, sizeof(gid), n);
}


long
header_ty::size_get()
{
      return octal(size, sizeof(size));
}


void
header_ty::size_set(long n)
{
      to_octal(size, sizeof(size), n);
}


long
header_ty::mtime_get()
{
      return octal(mtime, sizeof(mtime));
}


void
header_ty::mtime_set(long n)
{
      to_octal(mtime, sizeof(mtime), n);
}


long
header_ty::chksum_get()
{
      return octal(chksum, sizeof(chksum));
}


void
header_ty::chksum_set(long n)
{
      to_octal(chksum, sizeof(chksum), n);
}


int
header_ty::linkflag_get()
{
      return (unsigned char)linkflag;
}


void
header_ty::linkflag_set(int n)
{
      linkflag = n;
}


rcstring
header_ty::linkname_get()
{
      return rcstring(linkname, strnlen(linkname, sizeof(linkname)));
}


void
header_ty::linkname_set(const rcstring &arg)
{
      string_field_set(linkname, sizeof(linkname), arg);
}


rcstring
header_ty::uname_get()
{
      return rcstring(uname, strnlen(uname, sizeof(uname)));
}


void
header_ty::uname_set(const rcstring &arg)
{
      string_field_set(uname, sizeof(uname), arg);
}


rcstring
header_ty::gname_get()
{
      return rcstring(gname, strnlen(gname, sizeof(gname)));
}


void
header_ty::gname_set(const rcstring &arg)
{
      string_field_set(gname, sizeof(gname), arg);
}


long
header_ty::devmajor_get()
{
      return octal(devmajor, sizeof(devmajor));
}


void
header_ty::devmajor_set(long n)
{
      to_octal(devmajor, sizeof(devmajor), n);
}


long
header_ty::devminor_get()
{
      return octal(devminor, sizeof(devminor));
}


void
header_ty::devminor_set(long n)
{
      to_octal(devminor, sizeof(devminor), n);
}


long
header_ty::calculate_checksum()
{
      unsigned char *cp = (unsigned char *)this;
      unsigned char *ep = (unsigned char *)this->chksum;
      long sum = ((unsigned char)' ') * sizeof(this->chksum);
      while (cp < ep)
            sum += *cp++;
      cp = (unsigned char *)(this->chksum + sizeof(this->chksum));
      ep = (unsigned char *)this + TBLOCK;
      while (cp < ep)
            sum += *cp++;
      return sum;
}


#include <ac/stdio.h>


void
header_ty::dump()
{
      int j, k;
      unsigned char *cp = (unsigned char *)this;
      for (j = 0; j < TBLOCK; j += 16)
      {
            fprintf(stderr, "%03X:", j);
            for (k = 0; k < 16; ++k)
                  fprintf(stderr, " %02X", cp[j + k]);
            fprintf(stderr, "  ");
            for (k = 0; k < 16; ++k)
            {
                  int c = cp[j + k] & 0x7F;
                  if (c < ' ' || c > '~')
                        c = '.';
                  fputc(c, stderr);
            }
            fputc('\n', stderr);
      }
}

Generated by  Doxygen 1.6.0   Back to index