fifolog_create.c revision 306910
1274101Sbrooks/*- 2244541Sbrooks * Copyright (c) 2005-2008 Poul-Henning Kamp 3244541Sbrooks * All rights reserved. 4244541Sbrooks * 5244541Sbrooks * Redistribution and use in source and binary forms, with or without 6244541Sbrooks * modification, are permitted provided that the following conditions 7244541Sbrooks * are met: 8244541Sbrooks * 1. Redistributions of source code must retain the above copyright 9244541Sbrooks * notice, this list of conditions and the following disclaimer. 10244541Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 11244541Sbrooks * notice, this list of conditions and the following disclaimer in the 12244541Sbrooks * documentation and/or other materials provided with the distribution. 13244541Sbrooks * 14244541Sbrooks * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15244541Sbrooks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16244541Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17244541Sbrooks * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18244541Sbrooks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19244541Sbrooks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20244541Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21244541Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22244541Sbrooks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23244541Sbrooks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24244541Sbrooks * SUCH DAMAGE. 25244541Sbrooks * 26244541Sbrooks * $FreeBSD: stable/10/usr.sbin/fifolog/lib/fifolog_create.c 306910 2016-10-09 19:58:27Z pfg $ 27244541Sbrooks */ 28244541Sbrooks 29244541Sbrooks#include <assert.h> 30244541Sbrooks#include <errno.h> 31244541Sbrooks#include <stdio.h> 32244541Sbrooks#include <string.h> 33244541Sbrooks#include <unistd.h> 34244541Sbrooks#include <fcntl.h> 35244541Sbrooks#include <stdlib.h> 36244541Sbrooks#include <sys/endian.h> 37244541Sbrooks#include <sys/stat.h> 38244541Sbrooks#include <sys/disk.h> 39244541Sbrooks 40244541Sbrooks#include "fifolog.h" 41244541Sbrooks#include "libfifolog.h" 42244541Sbrooks 43244541Sbrooksconst char * 44244541Sbrooksfifolog_create(const char *fn, off_t size, ssize_t recsize) 45244541Sbrooks{ 46244541Sbrooks int i, fd; 47244541Sbrooks ssize_t u; 48244541Sbrooks off_t ms; 49244541Sbrooks struct stat st; 50244541Sbrooks char *buf; 51244541Sbrooks int created; 52244541Sbrooks 53244541Sbrooks fd = open(fn, O_WRONLY | O_TRUNC | O_EXCL | O_CREAT, 0644); 54244541Sbrooks if (fd < 0) { 55244541Sbrooks created = 0; 56244541Sbrooks fd = open(fn, O_WRONLY); 57244541Sbrooks if (fd < 0) 58244541Sbrooks return ("Could not open"); 59244541Sbrooks } else 60244541Sbrooks created = 1; 61244541Sbrooks 62244541Sbrooks /* Default sectorsize is 512 */ 63244541Sbrooks if (recsize == 0) 64244541Sbrooks recsize = 512; 65244541Sbrooks 66244541Sbrooks /* See what we got... */ 67244541Sbrooks i = fstat(fd, &st); 68244541Sbrooks assert(i == 0); 69244541Sbrooks if (!S_ISBLK(st.st_mode) && 70274101Sbrooks !S_ISCHR(st.st_mode) && 71244541Sbrooks !S_ISREG(st.st_mode)) { 72244541Sbrooks assert(!close (fd)); 73244541Sbrooks return ("Wrong file type"); 74244541Sbrooks } 75244541Sbrooks 76244541Sbrooks if(!created && S_ISREG(st.st_mode)) { 77244541Sbrooks assert(!close (fd)); 78244541Sbrooks return ("Wrong file type"); 79244541Sbrooks } 80244541Sbrooks 81244541Sbrooks /* For raw disk with larger sectors: use 1 sector */ 82244541Sbrooks i = ioctl(fd, DIOCGSECTORSIZE, &u); 83258655Sbrooks if (i == 0 && (u > recsize || (recsize % u) != 0)) 84256996Sbrooks recsize = u; 85244541Sbrooks 86244541Sbrooks /* If no configured size, or too large for disk, use device size */ 87244541Sbrooks i = ioctl(fd, DIOCGMEDIASIZE, &ms); 88244541Sbrooks if (i == 0 && (size == 0 || size > ms)) 89244541Sbrooks size = ms; 90244541Sbrooks 91244541Sbrooks if (size == 0 && S_ISREG(st.st_mode)) 92244541Sbrooks size = st.st_size; 93244541Sbrooks 94244541Sbrooks if (size == 0) 95244541Sbrooks size = recsize * (off_t)(24*60*60); 96244541Sbrooks 97244541Sbrooks if (S_ISREG(st.st_mode) && ftruncate(fd, size) < 0) 98244541Sbrooks return ("Could not ftrunc"); 99244541Sbrooks 100244541Sbrooks buf = calloc(1, recsize); 101244541Sbrooks if (buf == NULL) 102244541Sbrooks return ("Could not malloc"); 103244541Sbrooks 104244541Sbrooks strcpy(buf, FIFOLOG_FMT_MAGIC); /*lint !e64 */ 105274101Sbrooks be32enc(buf + FIFOLOG_OFF_BS, recsize); 106244541Sbrooks if (recsize != pwrite(fd, buf, recsize, 0)) { 107244541Sbrooks i = errno; 108244541Sbrooks free(buf); 109244541Sbrooks errno = i; 110244541Sbrooks return ("Could not write first sector"); 111244541Sbrooks } 112244541Sbrooks memset(buf, 0, recsize); 113244541Sbrooks if ((int)recsize != pwrite(fd, buf, recsize, recsize)) { 114244541Sbrooks i = errno; 115244541Sbrooks free(buf); 116244541Sbrooks errno = i; 117244541Sbrooks return ("Could not write second sector"); 118244541Sbrooks } 119244541Sbrooks free(buf); 120244541Sbrooks assert(0 == close(fd)); 121244541Sbrooks return (NULL); 122244541Sbrooks} 123244541Sbrooks