test_option_c.c revision 299529
1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm#include "test.h" 26228753Smm__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/test/test_option_c.c 299529 2016-05-12 10:16:16Z mm $"); 27228753Smm 28228753Smmstatic int 29228753Smmis_octal(const char *p, size_t l) 30228753Smm{ 31228753Smm while (l > 0) { 32228753Smm if (*p < '0' || *p > '7') 33228753Smm return (0); 34228753Smm --l; 35228753Smm ++p; 36228753Smm } 37228753Smm return (1); 38228753Smm} 39228753Smm 40228753Smmstatic int 41228753Smmfrom_octal(const char *p, size_t l) 42228753Smm{ 43228753Smm int r = 0; 44228753Smm 45228753Smm while (l > 0) { 46228753Smm r *= 8; 47228753Smm r += *p - '0'; 48228753Smm --l; 49228753Smm ++p; 50228753Smm } 51228753Smm return (r); 52228753Smm} 53228753Smm 54232153Smm#if !defined(_WIN32) || defined(__CYGWIN__) 55232153Smmstatic int 56232153Smmnlinks(const char *p) 57232153Smm{ 58232153Smm struct stat st; 59232153Smm assertEqualInt(0, stat(p, &st)); 60232153Smm return st.st_nlink; 61232153Smm} 62232153Smm#endif 63232153Smm 64228753SmmDEFINE_TEST(test_option_c) 65228753Smm{ 66228753Smm FILE *filelist; 67228753Smm int r; 68299529Smm int uid = 1000; 69299529Smm int dev, ino, gid = 1000; 70228753Smm time_t t, now; 71228753Smm char *p, *e; 72228753Smm size_t s; 73228753Smm 74228753Smm assertUmask(0); 75228753Smm 76228753Smm /* 77228753Smm * Create an assortment of files. 78228753Smm * TODO: Extend this to cover more filetypes. 79228753Smm */ 80228753Smm filelist = fopen("filelist", "w"); 81228753Smm 82228753Smm /* "file" */ 83228753Smm assertMakeFile("file", 0644, "1234567890"); 84228753Smm fprintf(filelist, "file\n"); 85228753Smm 86228753Smm /* "symlink" */ 87228753Smm if (canSymlink()) { 88228753Smm assertMakeSymlink("symlink", "file"); 89228753Smm fprintf(filelist, "symlink\n"); 90228753Smm } 91228753Smm 92228753Smm /* "dir" */ 93228753Smm assertMakeDir("dir", 0775); 94228753Smm /* Record some facts about what we just created: */ 95228753Smm now = time(NULL); /* They were all created w/in last two seconds. */ 96228753Smm fprintf(filelist, "dir\n"); 97228753Smm 98228753Smm /* Use the cpio program to create an archive. */ 99228753Smm fclose(filelist); 100299529Smm r = systemf("%s -R 1000:1000 -oc <filelist >basic.out 2>basic.err", testprog); 101228753Smm /* Verify that nothing went to stderr. */ 102228753Smm assertTextFileContents("1 block\n", "basic.err"); 103228753Smm 104228753Smm /* Assert that the program finished. */ 105228753Smm failure("%s -oc crashed", testprog); 106228753Smm if (!assertEqualInt(r, 0)) 107228753Smm return; 108228753Smm 109228753Smm /* Verify that stdout is a well-formed cpio file in "odc" format. */ 110228753Smm p = slurpfile(&s, "basic.out"); 111228753Smm assertEqualInt(s, 512); 112228753Smm e = p; 113228753Smm 114228753Smm /* 115228753Smm * Some of these assertions could be stronger, but it's 116228753Smm * a little tricky because they depend on the local environment. 117228753Smm */ 118228753Smm 119228753Smm /* First entry is "file" */ 120228753Smm assert(is_octal(e, 76)); /* Entire header is octal digits. */ 121228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 122228753Smm assert(is_octal(e + 6, 6)); /* dev */ 123228753Smm dev = from_octal(e + 6, 6); 124228753Smm assert(is_octal(e + 12, 6)); /* ino */ 125228753Smm ino = from_octal(e + 12, 6); 126228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) 127228753Smm /* Group members bits and others bits do not work. */ 128228753Smm assertEqualMem(e + 18, "100666", 6); /* Mode */ 129228753Smm#else 130228753Smm assertEqualMem(e + 18, "100644", 6); /* Mode */ 131228753Smm#endif 132228753Smm if (uid < 0) 133228753Smm uid = from_octal(e + 24, 6); 134228753Smm assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ 135228753Smm assert(is_octal(e + 30, 6)); /* gid */ 136228753Smm gid = from_octal(e + 30, 6); 137228753Smm assertEqualMem(e + 36, "000001", 6); /* nlink */ 138228753Smm failure("file entries should not have rdev set (dev field was 0%o)", 139228753Smm dev); 140228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 141228753Smm t = from_octal(e + 48, 11); /* mtime */ 142228753Smm assert(t <= now); /* File wasn't created in future. */ 143228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 144228753Smm assertEqualMem(e + 59, "000005", 6); /* Name size */ 145228753Smm assertEqualMem(e + 65, "00000000012", 11); /* File size */ 146228753Smm assertEqualMem(e + 76, "file\0", 5); /* Name contents */ 147228753Smm assertEqualMem(e + 81, "1234567890", 10); /* File contents */ 148228753Smm e += 91; 149228753Smm 150228753Smm /* "symlink" pointing to "file" */ 151228753Smm if (canSymlink()) { 152228753Smm assert(is_octal(e, 76)); /* Entire header is octal digits. */ 153228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 154228753Smm assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */ 155228753Smm assert(ino != from_octal(e + 12, 6)); /* ino */ 156228753Smm#if !defined(_WIN32) || defined(__CYGWIN__) 157228753Smm /* On Windows, symbolic link and group members bits and 158228753Smm * others bits do not work. */ 159228753Smm assertEqualMem(e + 18, "120777", 6); /* Mode */ 160228753Smm#endif 161228753Smm assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ 162228753Smm assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */ 163228753Smm assertEqualMem(e + 36, "000001", 6); /* nlink */ 164228753Smm failure("file entries should have rdev == 0 (dev was 0%o)", 165228753Smm from_octal(e + 6, 6)); 166228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 167228753Smm t = from_octal(e + 48, 11); /* mtime */ 168228753Smm assert(t <= now); /* File wasn't created in future. */ 169228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 170228753Smm assertEqualMem(e + 59, "000010", 6); /* Name size */ 171228753Smm assertEqualMem(e + 65, "00000000004", 11); /* File size */ 172228753Smm assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */ 173228753Smm assertEqualMem(e + 84, "file", 4); /* Symlink target. */ 174228753Smm e += 88; 175228753Smm } 176228753Smm 177228753Smm /* "dir" */ 178228753Smm assert(is_octal(e, 76)); 179228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 180228753Smm /* Dev should be same as first entry. */ 181228753Smm assert(is_octal(e + 6, 6)); /* dev */ 182228753Smm assertEqualInt(dev, from_octal(e + 6, 6)); 183228753Smm /* Ino must be different from first entry. */ 184228753Smm assert(is_octal(e + 12, 6)); /* ino */ 185228753Smm assert(ino != from_octal(e + 12, 6)); 186228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) 187228753Smm /* Group members bits and others bits do not work. */ 188228753Smm assertEqualMem(e + 18, "040777", 6); /* Mode */ 189228753Smm#else 190232153Smm /* Accept 042775 to accommodate systems where sgid bit propagates. */ 191228753Smm if (memcmp(e + 18, "042775", 6) != 0) 192228753Smm assertEqualMem(e + 18, "040775", 6); /* Mode */ 193228753Smm#endif 194232153Smm assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */ 195228753Smm /* Gid should be same as first entry. */ 196228753Smm assert(is_octal(e + 30, 6)); /* gid */ 197228753Smm assertEqualInt(gid, from_octal(e + 30, 6)); 198232153Smm 199232153Smm#if !defined(_WIN32) || defined(__CYGWIN__) 200232153Smm assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */ 201228753Smm#endif 202232153Smm 203228753Smm t = from_octal(e + 48, 11); /* mtime */ 204228753Smm assert(t <= now); /* File wasn't created in future. */ 205228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 206228753Smm assertEqualMem(e + 59, "000004", 6); /* Name size */ 207228753Smm assertEqualMem(e + 65, "00000000000", 11); /* File size */ 208228753Smm assertEqualMem(e + 76, "dir\0", 4); /* name */ 209228753Smm e += 80; 210228753Smm 211228753Smm /* TODO: Verify other types of entries. */ 212228753Smm 213228753Smm /* Last entry is end-of-archive marker. */ 214228753Smm assert(is_octal(e, 76)); 215228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 216228753Smm assertEqualMem(e + 6, "000000", 6); /* dev */ 217228753Smm assertEqualMem(e + 12, "000000", 6); /* ino */ 218228753Smm assertEqualMem(e + 18, "000000", 6); /* Mode */ 219228753Smm assertEqualMem(e + 24, "000000", 6); /* uid */ 220228753Smm assertEqualMem(e + 30, "000000", 6); /* gid */ 221228753Smm assertEqualMem(e + 36, "000001", 6); /* Nlink */ 222228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 223228753Smm assertEqualMem(e + 48, "00000000000", 11); /* mtime */ 224228753Smm assertEqualMem(e + 59, "000013", 6); /* Name size */ 225228753Smm assertEqualMem(e + 65, "00000000000", 11); /* File size */ 226228753Smm assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */ 227228753Smm 228228753Smm free(p); 229228753Smm} 230