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