mirror of https://github.com/ventoy/Ventoy
151 lines
3.4 KiB
C
151 lines
3.4 KiB
C
/*
|
|
* Create a squashfs filesystem. This is a highly compressed read only
|
|
* filesystem.
|
|
*
|
|
* Copyright (c) 2012
|
|
* Phillip Lougher <phillip@squashfs.org.uk>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2,
|
|
* or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* read_file.c
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
|
|
#include "error.h"
|
|
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define MAX_LINE 16384
|
|
|
|
/*
|
|
* Read file, passing each line to parse_line() for
|
|
* parsing.
|
|
*
|
|
* Lines can be split across multiple lines using "\".
|
|
*
|
|
* Blank lines and comment lines indicated by # are supported.
|
|
*/
|
|
int read_file(char *filename, char *type, int (parse_line)(char *))
|
|
{
|
|
FILE *fd;
|
|
char *def, *err, *line = NULL;
|
|
int res, size = 0;
|
|
|
|
fd = fopen(filename, "r");
|
|
if(fd == NULL) {
|
|
ERROR("Could not open %s device file \"%s\" because %s\n",
|
|
type, filename, strerror(errno));
|
|
return FALSE;
|
|
}
|
|
|
|
while(1) {
|
|
int total = 0;
|
|
|
|
while(1) {
|
|
int len;
|
|
|
|
if(total + (MAX_LINE + 1) > size) {
|
|
line = realloc(line, size += (MAX_LINE + 1));
|
|
if(line == NULL)
|
|
MEM_ERROR();
|
|
}
|
|
|
|
err = fgets(line + total, MAX_LINE + 1, fd);
|
|
if(err == NULL)
|
|
break;
|
|
|
|
len = strlen(line + total);
|
|
total += len;
|
|
|
|
if(len == MAX_LINE && line[total - 1] != '\n') {
|
|
/* line too large */
|
|
ERROR("Line too long when reading "
|
|
"%s file \"%s\", larger than "
|
|
"%d bytes\n", type, filename, MAX_LINE);
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* Remove '\n' terminator if it exists (the last line
|
|
* in the file may not be '\n' terminated)
|
|
*/
|
|
if(len && line[total - 1] == '\n') {
|
|
line[-- total] = '\0';
|
|
len --;
|
|
}
|
|
|
|
/*
|
|
* If no line continuation then jump out to
|
|
* process line. Note, we have to be careful to
|
|
* check for "\\" (backslashed backslash) and to
|
|
* ensure we don't look at the previous line
|
|
*/
|
|
if(len == 0 || line[total - 1] != '\\' || (len >= 2 &&
|
|
strcmp(line + total - 2, "\\\\") == 0))
|
|
break;
|
|
else
|
|
total --;
|
|
}
|
|
|
|
if(err == NULL) {
|
|
if(ferror(fd)) {
|
|
ERROR("Reading %s file \"%s\" failed "
|
|
"because %s\n", type, filename,
|
|
strerror(errno));
|
|
goto failed;
|
|
}
|
|
|
|
/*
|
|
* At EOF, normally we'll be finished, but, have to
|
|
* check for special case where we had "\" line
|
|
* continuation and then hit EOF immediately afterwards
|
|
*/
|
|
if(total == 0)
|
|
break;
|
|
else
|
|
line[total] = '\0';
|
|
}
|
|
|
|
/* Skip any leading whitespace */
|
|
for(def = line; isspace(*def); def ++);
|
|
|
|
/* if line is now empty after skipping characters, skip it */
|
|
if(*def == '\0')
|
|
continue;
|
|
|
|
/* if comment line, skip */
|
|
if(*def == '#')
|
|
continue;
|
|
|
|
res = parse_line(def);
|
|
if(res == FALSE)
|
|
goto failed;
|
|
}
|
|
|
|
fclose(fd);
|
|
free(line);
|
|
return TRUE;
|
|
|
|
failed:
|
|
fclose(fd);
|
|
free(line);
|
|
return FALSE;
|
|
}
|