1 /* $OpenBSD: util.c,v 1.6 2015/10/07 03:06:46 krw Exp $ */ 2 3 /* 4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/stat.h> 20 #include <err.h> 21 #include <errno.h> 22 #include <fcntl.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 #include <limits.h> 28 29 #include "installboot.h" 30 31 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 32 33 #define BUFSIZE 512 34 35 void 36 filecopy(const char *srcfile, const char *dstfile) 37 { 38 struct stat sb; 39 ssize_t sz, n; 40 int sfd, dfd; 41 char *buf; 42 43 if ((buf = malloc(BUFSIZE)) == NULL) 44 err(1, "malloc"); 45 46 sfd = open(srcfile, O_RDONLY); 47 if (sfd == -1) 48 err(1, "open %s", srcfile); 49 if (fstat(sfd, &sb) == -1) 50 err(1, "fstat"); 51 sz = sb.st_size; 52 53 dfd = open(dstfile, O_WRONLY|O_CREAT); 54 if (dfd == -1) 55 err(1, "open %s", dstfile); 56 if (fchown(dfd, 0, 0) == -1) 57 if (errno != EINVAL) 58 err(1, "chown"); 59 if (fchmod(dfd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) 60 err(1, "chmod"); 61 62 while (sz > 0) { 63 n = MINIMUM(sz, BUFSIZE); 64 if ((n = read(sfd, buf, n)) == -1) 65 err(1, "read"); 66 sz -= n; 67 if (write(dfd, buf, n) != n) 68 err(1, "write"); 69 } 70 71 ftruncate(dfd, sb.st_size); 72 73 close(dfd); 74 close(sfd); 75 free(buf); 76 } 77 78 char * 79 fileprefix(const char *base, const char *path) 80 { 81 char *r, *s; 82 int n; 83 84 if ((s = malloc(PATH_MAX)) == NULL) 85 err(1, "malloc"); 86 n = snprintf(s, PATH_MAX, "%s/%s", base, path); 87 if (n < 1 || n >= PATH_MAX) 88 err(1, "snprintf"); 89 if ((r = realpath(s, NULL)) == NULL) 90 err(1, "realpath"); 91 free(s); 92 93 return r; 94 } 95 96 /* 97 * Adapted from Hacker's Delight crc32b(). 98 * 99 * To quote http://www.hackersdelight.org/permissions.htm : 100 * 101 * "You are free to use, copy, and distribute any of the code on 102 * this web site, whether modified by you or not. You need not give 103 * attribution. This includes the algorithms (some of which appear 104 * in Hacker's Delight), the Hacker's Assistant, and any code submitted 105 * by readers. Submitters implicitly agree to this." 106 */ 107 u_int32_t 108 crc32(const u_char *buf, const u_int32_t size) 109 { 110 int j; 111 u_int32_t i, byte, crc, mask; 112 113 crc = 0xFFFFFFFF; 114 115 for (i = 0; i < size; i++) { 116 byte = buf[i]; /* Get next byte. */ 117 crc = crc ^ byte; 118 for (j = 7; j >= 0; j--) { /* Do eight times. */ 119 mask = -(crc & 1); 120 crc = (crc >> 1) ^ (0xEDB88320 & mask); 121 } 122 } 123 124 return ~crc; 125 } 126