1c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher/* 2c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Create a squashfs filesystem. This is a highly compressed read only 3c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * filesystem. 4c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 5c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Copyright (c) 2012 6c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Phillip Lougher <phillip@squashfs.org.uk> 7c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 8c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * This program is free software; you can redistribute it and/or 9c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * modify it under the terms of the GNU General Public License 10c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * as published by the Free Software Foundation; either version 2, 11c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * or (at your option) any later version. 12c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 13c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * This program is distributed in the hope that it will be useful, 14c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * but WITHOUT ANY WARRANTY; without even the implied warranty of 15c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * GNU General Public License for more details. 17c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 18c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * You should have received a copy of the GNU General Public License 19c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * along with this program; if not, write to the Free Software 20c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 22c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * read_file.c 23c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher */ 24c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 25c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include <stdio.h> 26c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include <stdlib.h> 27c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include <string.h> 28c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include <ctype.h> 29c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include <errno.h> 30c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 31c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#include "error.h" 32c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 33c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#define TRUE 1 34c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#define FALSE 0 35c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher#define MAX_LINE 16384 36c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 37c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher/* 38c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Read file, passing each line to parse_line() for 39c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * parsing. 40c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 41c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Lines can be split across multiple lines using "\". 42c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * 43c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Blank lines and comment lines indicated by # are supported. 44c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher */ 45c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougherint read_file(char *filename, char *type, int (parse_line)(char *)) 46c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher{ 47c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher FILE *fd; 48c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher char *def, *err, *line = NULL; 49c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher int res, size = 0; 50c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 51c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher fd = fopen(filename, "r"); 52c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(fd == NULL) { 53c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher ERROR("Could not open %s device file \"%s\" because %s\n", 54c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher type, filename, strerror(errno)); 55c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher return FALSE; 56c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 57c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 58c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher while(1) { 59c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher int total = 0; 60c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 61c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher while(1) { 62c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher int len; 63c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 64c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(total + (MAX_LINE + 1) > size) { 65c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher line = realloc(line, size += (MAX_LINE + 1)); 669a222122c59e370e8e80a114c7ddfbabc0aef746Phillip Lougher if(line == NULL) 679a222122c59e370e8e80a114c7ddfbabc0aef746Phillip Lougher MEM_ERROR(); 68c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 69c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 70c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher err = fgets(line + total, MAX_LINE + 1, fd); 71c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(err == NULL) 72c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher break; 73c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 74c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher len = strlen(line + total); 75c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher total += len; 76c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 77c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(len == MAX_LINE && line[total - 1] != '\n') { 78c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* line too large */ 79c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher ERROR("Line too long when reading " 80c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher "%s file \"%s\", larger than " 81c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher "%d bytes\n", type, filename, MAX_LINE); 82c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher goto failed; 83c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 84c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 85c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* 86c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * Remove '\n' terminator if it exists (the last line 87c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * in the file may not be '\n' terminated) 88c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher */ 89c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(len && line[total - 1] == '\n') { 90c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher line[-- total] = '\0'; 91c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher len --; 92c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 93c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 94c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* 95c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * If no line continuation then jump out to 96c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * process line. Note, we have to be careful to 97c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * check for "\\" (backslashed backslash) and to 98c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * ensure we don't look at the previous line 99c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher */ 100c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(len == 0 || line[total - 1] != '\\' || (len >= 2 && 101c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher strcmp(line + total - 2, "\\\\") == 0)) 102c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher break; 103c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher else 104c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher total --; 105c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 106c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 107c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(err == NULL) { 108c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(ferror(fd)) { 109c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher ERROR("Reading %s file \"%s\" failed " 110c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher "because %s\n", type, filename, 111c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher strerror(errno)); 112c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher goto failed; 113c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 114c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 115c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* 116c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * At EOF, normally we'll be finished, but, have to 117c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * check for special case where we had "\" line 118c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher * continuation and then hit EOF immediately afterwards 119c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher */ 120c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(total == 0) 121c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher break; 122c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher else 123c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher line[total] = '\0'; 124c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 125c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 126c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* Skip any leading whitespace */ 127c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher for(def = line; isspace(*def); def ++); 128c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 129c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* if line is now empty after skipping characters, skip it */ 130c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(*def == '\0') 131c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher continue; 132c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 133c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher /* if comment line, skip */ 134c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(*def == '#') 135c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher continue; 136c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 137c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher res = parse_line(def); 138c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher if(res == FALSE) 139a1305bac848f1d95479a9687d31fa87a849ea4a4Phillip Lougher goto failed; 140c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher } 141c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 142c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher fclose(fd); 143c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher free(line); 144c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher return TRUE; 145c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher 146c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougherfailed: 147c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher fclose(fd); 148c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher free(line); 149c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher return FALSE; 150c4b044f565ba7882e73acf6132b9d4be59690910Phillip Lougher} 151