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$"); 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; 68228753Smm int uid = -1; 69228753Smm int dev, ino, gid; 70228753Smm time_t t, now; 71228753Smm char *p, *e; 72228753Smm size_t s; 73228753Smm 74228753Smm assertUmask(0); 75228753Smm 76228753Smm#if !defined(_WIN32) 77228753Smm uid = getuid(); 78228753Smm#endif 79228753Smm 80228753Smm /* 81228753Smm * Create an assortment of files. 82228753Smm * TODO: Extend this to cover more filetypes. 83228753Smm */ 84228753Smm filelist = fopen("filelist", "w"); 85228753Smm 86228753Smm /* "file" */ 87228753Smm assertMakeFile("file", 0644, "1234567890"); 88228753Smm fprintf(filelist, "file\n"); 89228753Smm 90228753Smm /* "symlink" */ 91228753Smm if (canSymlink()) { 92228753Smm assertMakeSymlink("symlink", "file"); 93228753Smm fprintf(filelist, "symlink\n"); 94228753Smm } 95228753Smm 96228753Smm /* "dir" */ 97228753Smm assertMakeDir("dir", 0775); 98228753Smm /* Record some facts about what we just created: */ 99228753Smm now = time(NULL); /* They were all created w/in last two seconds. */ 100228753Smm fprintf(filelist, "dir\n"); 101228753Smm 102228753Smm /* Use the cpio program to create an archive. */ 103228753Smm fclose(filelist); 104228753Smm r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog); 105228753Smm /* Verify that nothing went to stderr. */ 106228753Smm assertTextFileContents("1 block\n", "basic.err"); 107228753Smm 108228753Smm /* Assert that the program finished. */ 109228753Smm failure("%s -oc crashed", testprog); 110228753Smm if (!assertEqualInt(r, 0)) 111228753Smm return; 112228753Smm 113228753Smm /* Verify that stdout is a well-formed cpio file in "odc" format. */ 114228753Smm p = slurpfile(&s, "basic.out"); 115228753Smm assertEqualInt(s, 512); 116228753Smm e = p; 117228753Smm 118228753Smm /* 119228753Smm * Some of these assertions could be stronger, but it's 120228753Smm * a little tricky because they depend on the local environment. 121228753Smm */ 122228753Smm 123228753Smm /* First entry is "file" */ 124228753Smm assert(is_octal(e, 76)); /* Entire header is octal digits. */ 125228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 126228753Smm assert(is_octal(e + 6, 6)); /* dev */ 127228753Smm dev = from_octal(e + 6, 6); 128228753Smm assert(is_octal(e + 12, 6)); /* ino */ 129228753Smm ino = from_octal(e + 12, 6); 130228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) 131228753Smm /* Group members bits and others bits do not work. */ 132228753Smm assertEqualMem(e + 18, "100666", 6); /* Mode */ 133228753Smm#else 134228753Smm assertEqualMem(e + 18, "100644", 6); /* Mode */ 135228753Smm#endif 136228753Smm if (uid < 0) 137228753Smm uid = from_octal(e + 24, 6); 138228753Smm assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ 139228753Smm assert(is_octal(e + 30, 6)); /* gid */ 140228753Smm gid = from_octal(e + 30, 6); 141228753Smm assertEqualMem(e + 36, "000001", 6); /* nlink */ 142228753Smm failure("file entries should not have rdev set (dev field was 0%o)", 143228753Smm dev); 144228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 145228753Smm t = from_octal(e + 48, 11); /* mtime */ 146228753Smm assert(t <= now); /* File wasn't created in future. */ 147228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 148228753Smm assertEqualMem(e + 59, "000005", 6); /* Name size */ 149228753Smm assertEqualMem(e + 65, "00000000012", 11); /* File size */ 150228753Smm assertEqualMem(e + 76, "file\0", 5); /* Name contents */ 151228753Smm assertEqualMem(e + 81, "1234567890", 10); /* File contents */ 152228753Smm e += 91; 153228753Smm 154228753Smm /* "symlink" pointing to "file" */ 155228753Smm if (canSymlink()) { 156228753Smm assert(is_octal(e, 76)); /* Entire header is octal digits. */ 157228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 158228753Smm assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */ 159228753Smm assert(ino != from_octal(e + 12, 6)); /* ino */ 160228753Smm#if !defined(_WIN32) || defined(__CYGWIN__) 161228753Smm /* On Windows, symbolic link and group members bits and 162228753Smm * others bits do not work. */ 163228753Smm assertEqualMem(e + 18, "120777", 6); /* Mode */ 164228753Smm#endif 165228753Smm assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ 166228753Smm assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */ 167228753Smm assertEqualMem(e + 36, "000001", 6); /* nlink */ 168228753Smm failure("file entries should have rdev == 0 (dev was 0%o)", 169228753Smm from_octal(e + 6, 6)); 170228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 171228753Smm t = from_octal(e + 48, 11); /* mtime */ 172228753Smm assert(t <= now); /* File wasn't created in future. */ 173228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 174228753Smm assertEqualMem(e + 59, "000010", 6); /* Name size */ 175228753Smm assertEqualMem(e + 65, "00000000004", 11); /* File size */ 176228753Smm assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */ 177228753Smm assertEqualMem(e + 84, "file", 4); /* Symlink target. */ 178228753Smm e += 88; 179228753Smm } 180228753Smm 181228753Smm /* "dir" */ 182228753Smm assert(is_octal(e, 76)); 183228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 184228753Smm /* Dev should be same as first entry. */ 185228753Smm assert(is_octal(e + 6, 6)); /* dev */ 186228753Smm assertEqualInt(dev, from_octal(e + 6, 6)); 187228753Smm /* Ino must be different from first entry. */ 188228753Smm assert(is_octal(e + 12, 6)); /* ino */ 189228753Smm assert(ino != from_octal(e + 12, 6)); 190228753Smm#if defined(_WIN32) && !defined(__CYGWIN__) 191228753Smm /* Group members bits and others bits do not work. */ 192228753Smm assertEqualMem(e + 18, "040777", 6); /* Mode */ 193228753Smm#else 194232153Smm /* Accept 042775 to accommodate systems where sgid bit propagates. */ 195228753Smm if (memcmp(e + 18, "042775", 6) != 0) 196228753Smm assertEqualMem(e + 18, "040775", 6); /* Mode */ 197228753Smm#endif 198232153Smm assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */ 199228753Smm /* Gid should be same as first entry. */ 200228753Smm assert(is_octal(e + 30, 6)); /* gid */ 201228753Smm assertEqualInt(gid, from_octal(e + 30, 6)); 202232153Smm 203232153Smm#if !defined(_WIN32) || defined(__CYGWIN__) 204232153Smm assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */ 205228753Smm#endif 206232153Smm 207228753Smm t = from_octal(e + 48, 11); /* mtime */ 208228753Smm assert(t <= now); /* File wasn't created in future. */ 209228753Smm assert(t >= now - 2); /* File was created w/in last 2 secs. */ 210228753Smm assertEqualMem(e + 59, "000004", 6); /* Name size */ 211228753Smm assertEqualMem(e + 65, "00000000000", 11); /* File size */ 212228753Smm assertEqualMem(e + 76, "dir\0", 4); /* name */ 213228753Smm e += 80; 214228753Smm 215228753Smm /* TODO: Verify other types of entries. */ 216228753Smm 217228753Smm /* Last entry is end-of-archive marker. */ 218228753Smm assert(is_octal(e, 76)); 219228753Smm assertEqualMem(e + 0, "070707", 6); /* Magic */ 220228753Smm assertEqualMem(e + 6, "000000", 6); /* dev */ 221228753Smm assertEqualMem(e + 12, "000000", 6); /* ino */ 222228753Smm assertEqualMem(e + 18, "000000", 6); /* Mode */ 223228753Smm assertEqualMem(e + 24, "000000", 6); /* uid */ 224228753Smm assertEqualMem(e + 30, "000000", 6); /* gid */ 225228753Smm assertEqualMem(e + 36, "000001", 6); /* Nlink */ 226228753Smm assertEqualMem(e + 42, "000000", 6); /* rdev */ 227228753Smm assertEqualMem(e + 48, "00000000000", 11); /* mtime */ 228228753Smm assertEqualMem(e + 59, "000013", 6); /* Name size */ 229228753Smm assertEqualMem(e + 65, "00000000000", 11); /* File size */ 230228753Smm assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */ 231228753Smm 232228753Smm free(p); 233228753Smm} 234