/** * @file utils.c Tar utility functions * * $Id: utils.c,v 1.5 2003/01/01 06:22:33 chipx86 Exp $ * * @Copyright (C) 1999-2003 The GNUpdate Project. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "tar.h" /* Octal to Integer */ int cxTarOctalToInt(const char *oct) { int i; sscanf(oct, "%o", &i); return i; } #if 0 int tarIoError(TarInfo *info) { int error = errno; /* fflush() could cause errno to change. */ fflush(stdout); fprintf(stderr, "tar.so: %s: %s\n", info->name, strerror(error)); return -2; } int tarSetModes(TarInfo *info) { struct utimbuf t; #ifdef HAVE_LCHOWN lchown(info->name, info->user_id, info->group_id); #else chown(info->name, info->user_id, info->group_id); #endif chmod(info->name, info->mode & ~S_IFMT); t.actime = time(0); t.modtime = info->mod_time; utime(info->name, &t); return 0; } int tarMkDir(TarInfo *info) { if (mkdir(info->name, info->mode & ~S_IFMT) != 0) { if (errno == EEXIST) { struct stat s; if (stat(info->name, &s) != 0 || !(s.st_mode & S_IFDIR)) return tarIoError(info); } else return tarIoError(info); } tarSetModes(info); return 0; } int tarMakeHardlink(TarInfo *info) { if (link(info->link_name, info->name) != 0) return tarIoError(info); tarSetModes(info); return 0; } int tarMakeSymlink(TarInfo *info) { if (symlink(info->link_name, info->name) != 0) return -2; /* tarIoError(info); ? */ tarSetModes(info); return 0; } int tarMakeSpecial(TarInfo *info) { if (mknod(info->name, info->mode, info->device) != 0) return -2; /* tarIoError(info); ? */ tarSetModes(info); return 0; } int tarDecodeHeader(char *block, TarInfo *info) { TarHeader *header = (TarHeader *)block; unsigned char *s = (unsigned char *)block; struct passwd *passwd = NULL; struct group *group = NULL; unsigned int i; long sum; long checksum; if (*header->user_name != NULL) passwd = getpwnam(header->user_name); if (*header->group_name != NULL) group = getgrnam(header->group_name); info->name = header->name; info->link_name = header->link_name; info->mode = (mode_t)tarOctalToLong(header->mode, sizeof(header->mode)); info->size = (size_t)tarOctalToLong(header->size, sizeof(header->size)); info->mod_time = (time_t)tarOctalToLong(header->mod_time, sizeof(header->mod_time)); info->device = ((tarOctalToLong(header->major_device, sizeof(header->major_device)) & 0xFF) << 8) | (tarOctalToLong(header->minor_device, sizeof(header->minor_device)) & 0xFF); checksum = tarOctalToLong(header->checksum, sizeof(header->checksum)); info->user_id = (uid_t)tarOctalToLong(header->user_id, sizeof(header->user_id)); info->group_id = (gid_t)tarOctalToLong(header->group_id, sizeof(header->group_id)); info->type = (TarFileType)header->link_flag; if (passwd != NULL) info->user_id = passwd->pw_uid; if (group != NULL) info->group_id = group->gr_gid; /* Treat checksum field as all blank. */ sum = ' ' * sizeof(header->checksum); for (i = tarChecksumOffset; i > 0; i--) sum += *s++; s += sizeof(header->checksum); /* Skip the real checksum field. */ for (i = (512 - tarChecksumOffset - sizeof(header->checksum)); i > 0; i--) sum += *s++; return (sum == checksum); } int tarExtractNextFile(TarInfo *info) { /* * If you don't want to extract the file, you must advance the tape * by the file size rounded up to the next 512-byte boundary and * return 0. */ /* TODO: Make this extract to the correct place! */ int fd = open(info->name, O_CREAT | O_TRUNC | O_WRONLY, info->mode & ~S_IFMT); char buffer[512]; } #endif