1662cb04cSPoul-Henning Kamp /*- 2662cb04cSPoul-Henning Kamp * Copyright (c) 2005-2008 Poul-Henning Kamp 3662cb04cSPoul-Henning Kamp * All rights reserved. 4662cb04cSPoul-Henning Kamp * 5662cb04cSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 6662cb04cSPoul-Henning Kamp * modification, are permitted provided that the following conditions 7662cb04cSPoul-Henning Kamp * are met: 8662cb04cSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 9662cb04cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 10662cb04cSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 11662cb04cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 12662cb04cSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 13662cb04cSPoul-Henning Kamp * 14662cb04cSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15662cb04cSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16662cb04cSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17662cb04cSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18662cb04cSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19662cb04cSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20662cb04cSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21662cb04cSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22662cb04cSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23662cb04cSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24662cb04cSPoul-Henning Kamp * SUCH DAMAGE. 25662cb04cSPoul-Henning Kamp * 26662cb04cSPoul-Henning Kamp * $FreeBSD$ 27662cb04cSPoul-Henning Kamp */ 28662cb04cSPoul-Henning Kamp 29662cb04cSPoul-Henning Kamp #include <assert.h> 30662cb04cSPoul-Henning Kamp #include <errno.h> 31662cb04cSPoul-Henning Kamp #include <stdio.h> 32662cb04cSPoul-Henning Kamp #include <string.h> 33662cb04cSPoul-Henning Kamp #include <unistd.h> 34662cb04cSPoul-Henning Kamp #include <fcntl.h> 35662cb04cSPoul-Henning Kamp #include <stdlib.h> 36662cb04cSPoul-Henning Kamp #include <sys/endian.h> 37662cb04cSPoul-Henning Kamp #include <sys/stat.h> 38662cb04cSPoul-Henning Kamp #include <sys/disk.h> 39662cb04cSPoul-Henning Kamp 40662cb04cSPoul-Henning Kamp #include "fifolog.h" 41662cb04cSPoul-Henning Kamp #include "libfifolog.h" 42662cb04cSPoul-Henning Kamp 43662cb04cSPoul-Henning Kamp const char * 44662cb04cSPoul-Henning Kamp fifolog_create(const char *fn, off_t size, unsigned recsize) 45662cb04cSPoul-Henning Kamp { 46662cb04cSPoul-Henning Kamp int i, fd; 47662cb04cSPoul-Henning Kamp unsigned u; 48662cb04cSPoul-Henning Kamp off_t ms; 49662cb04cSPoul-Henning Kamp struct stat st; 50662cb04cSPoul-Henning Kamp char *buf; 51662cb04cSPoul-Henning Kamp int created; 52662cb04cSPoul-Henning Kamp 53662cb04cSPoul-Henning Kamp fd = open(fn, O_WRONLY | O_TRUNC | O_EXCL | O_CREAT, 0644); 54662cb04cSPoul-Henning Kamp if (fd < 0) { 55662cb04cSPoul-Henning Kamp created = 0; 56662cb04cSPoul-Henning Kamp fd = open(fn, O_WRONLY); 57662cb04cSPoul-Henning Kamp if (fd < 0) 58662cb04cSPoul-Henning Kamp return ("Could not open"); 59662cb04cSPoul-Henning Kamp } else 60662cb04cSPoul-Henning Kamp created = 1; 61662cb04cSPoul-Henning Kamp 62662cb04cSPoul-Henning Kamp /* Default sectorsize is 512 */ 63662cb04cSPoul-Henning Kamp if (recsize == 0) 64662cb04cSPoul-Henning Kamp recsize = 512; 65662cb04cSPoul-Henning Kamp 66662cb04cSPoul-Henning Kamp /* See what we got... */ 67662cb04cSPoul-Henning Kamp i = fstat(fd, &st); 68662cb04cSPoul-Henning Kamp assert(i == 0); 69662cb04cSPoul-Henning Kamp if (!S_ISBLK(st.st_mode) && 70662cb04cSPoul-Henning Kamp !S_ISCHR(st.st_mode) && 71662cb04cSPoul-Henning Kamp !S_ISREG(st.st_mode)) { 72662cb04cSPoul-Henning Kamp assert(!close (fd)); 73662cb04cSPoul-Henning Kamp return ("Wrong file type"); 74662cb04cSPoul-Henning Kamp } 75662cb04cSPoul-Henning Kamp 76662cb04cSPoul-Henning Kamp if(!created && S_ISREG(st.st_mode)) { 77662cb04cSPoul-Henning Kamp assert(!close (fd)); 78662cb04cSPoul-Henning Kamp return ("Wrong file type"); 79662cb04cSPoul-Henning Kamp } 80662cb04cSPoul-Henning Kamp 81662cb04cSPoul-Henning Kamp /* For raw disk with larger sectors: use 1 sector */ 82662cb04cSPoul-Henning Kamp i = ioctl(fd, DIOCGSECTORSIZE, &u); 83662cb04cSPoul-Henning Kamp if (i == 0 && (u > recsize || (recsize % u) != 0)) 84662cb04cSPoul-Henning Kamp recsize = u; 85662cb04cSPoul-Henning Kamp 86662cb04cSPoul-Henning Kamp /* If no configured size, or too large for disk, use device size */ 87662cb04cSPoul-Henning Kamp i = ioctl(fd, DIOCGMEDIASIZE, &ms); 88662cb04cSPoul-Henning Kamp if (i == 0 && (size == 0 || size > ms)) 89662cb04cSPoul-Henning Kamp size = ms; 90662cb04cSPoul-Henning Kamp 91662cb04cSPoul-Henning Kamp if (size == 0 && S_ISREG(st.st_mode)) 92662cb04cSPoul-Henning Kamp size = st.st_size; 93662cb04cSPoul-Henning Kamp 94662cb04cSPoul-Henning Kamp if (size == 0) 95662cb04cSPoul-Henning Kamp size = recsize * (off_t)(24*60*60); 96662cb04cSPoul-Henning Kamp 97662cb04cSPoul-Henning Kamp if (S_ISREG(st.st_mode) && ftruncate(fd, size) < 0) 98662cb04cSPoul-Henning Kamp return ("Could not ftrunc"); 99662cb04cSPoul-Henning Kamp 100662cb04cSPoul-Henning Kamp buf = calloc(recsize, 1); 101662cb04cSPoul-Henning Kamp if (buf == NULL) 102662cb04cSPoul-Henning Kamp return ("Could not malloc"); 103662cb04cSPoul-Henning Kamp 104662cb04cSPoul-Henning Kamp strcpy(buf, FIFOLOG_FMT_MAGIC); /*lint !e64 */ 105662cb04cSPoul-Henning Kamp be32enc(buf + FIFOLOG_OFF_BS, recsize); 106662cb04cSPoul-Henning Kamp if ((int)recsize != pwrite(fd, buf, recsize, 0)) { 107662cb04cSPoul-Henning Kamp i = errno; 108662cb04cSPoul-Henning Kamp free(buf); 109662cb04cSPoul-Henning Kamp errno = i; 110662cb04cSPoul-Henning Kamp return ("Could not write first sector"); 111662cb04cSPoul-Henning Kamp } 112662cb04cSPoul-Henning Kamp memset(buf, 0, recsize); 113662cb04cSPoul-Henning Kamp if ((int)recsize != pwrite(fd, buf, recsize, recsize)) { 114662cb04cSPoul-Henning Kamp i = errno; 115662cb04cSPoul-Henning Kamp free(buf); 116662cb04cSPoul-Henning Kamp errno = i; 117662cb04cSPoul-Henning Kamp return ("Could not write second sector"); 118662cb04cSPoul-Henning Kamp } 119662cb04cSPoul-Henning Kamp free(buf); 120662cb04cSPoul-Henning Kamp assert(0 == close(fd)); 121662cb04cSPoul-Henning Kamp return (NULL); 122662cb04cSPoul-Henning Kamp } 123