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