241 lines
4.7 KiB
C
241 lines
4.7 KiB
C
/*
|
|
scconfig - library to query files and directories
|
|
Copyright (C) 2009..2012 Tibor Palinkas
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library 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
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA
|
|
|
|
Project page: http://repo.hu/projects/scconfig
|
|
Contact (email and IRC): http://igor2.repo.hu/contact.html
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include "db.h"
|
|
#include "libs.h"
|
|
#include "log.h"
|
|
#include "dep.h"
|
|
|
|
int file_size(const char *name)
|
|
{
|
|
struct stat buf;
|
|
if (stat(name, &buf) != 0)
|
|
return -1;
|
|
return buf.st_size;
|
|
}
|
|
|
|
char *tempdir_new(int logdepth, const char *suffix)
|
|
{
|
|
char s[1024];
|
|
char *cmd;
|
|
const char *tmp;
|
|
const char *mkdir, *emu;
|
|
unsigned int rn, n;
|
|
|
|
require("sys/tmp", logdepth+1, 1);
|
|
tmp = get("sys/tmp");
|
|
|
|
if (strlen(suffix) > sizeof(s) - strlen(tmp) - 32) {
|
|
fprintf(stderr, "Not enough room for creating temporary file name\n");
|
|
abort();
|
|
}
|
|
|
|
require("fstools/mkdir", logdepth+1, 1);
|
|
mkdir = get("fstools/mkdir");
|
|
|
|
emu = get("sys/emu");
|
|
if (emu == NULL)
|
|
emu = "";
|
|
|
|
for(n = 0; n < 128; n++) {
|
|
rn = rand() % 100000;
|
|
sprintf(s, "%sscc_%u%s", tmp, rn, suffix);
|
|
if (!exists(s)) {
|
|
char *s_esc = shell_escape_dup(s);
|
|
cmd = malloc(strlen(s_esc) + strlen(mkdir) + 16);
|
|
sprintf(cmd, "%s %s", mkdir, s_esc);
|
|
run_shell(logdepth+1, cmd, NULL);
|
|
free(s_esc);
|
|
free(cmd);
|
|
if (is_dir(s))
|
|
return strclone(s);
|
|
}
|
|
}
|
|
error("Couldn't find a suitable temp dir name\n");
|
|
abort();
|
|
}
|
|
|
|
char *tempfile_new_noabort(const char *suffix)
|
|
{
|
|
char s[1024];
|
|
const char *tmp;
|
|
unsigned int rn, n;
|
|
FILE *f;
|
|
|
|
|
|
require("/host/sys/tmp", 0, 1);
|
|
tmp = get("/host/sys/tmp");
|
|
if (strlen(suffix) > sizeof(s) - strlen(tmp) - 32) {
|
|
fprintf(stderr, "tempfile_new_noabort(): not enough room for creating temporary file name\n");
|
|
abort();
|
|
}
|
|
|
|
for(n = 0; n < 128; n++) {
|
|
rn = rand() % 100000;
|
|
sprintf(s, "%sscc_%u%s", tmp, rn, suffix);
|
|
if (!is_file(s)) { /* can not test for exists() because that would recurse is_dir */
|
|
f = fopen(s, "w");
|
|
if (f != NULL) {
|
|
fclose(f);
|
|
return strclone(s);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *tempfile_new(const char *suffix)
|
|
{
|
|
char *tmp;
|
|
|
|
tmp = tempfile_new_noabort(suffix);
|
|
if (tmp == NULL) {
|
|
error("Couldn't find a suitable temp file name\n");
|
|
abort();
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
char *tempfile_dump(const char *testcode, const char *suffix)
|
|
{
|
|
char *fn;
|
|
FILE *f;
|
|
|
|
fn = tempfile_new(suffix);
|
|
f = fopen(fn, "w");
|
|
fprintf(f, "%s", testcode);
|
|
fclose(f);
|
|
return fn;
|
|
}
|
|
|
|
char *load_file(const char *name)
|
|
{
|
|
int size;
|
|
char *content;
|
|
FILE *f;
|
|
|
|
size = file_size(name);
|
|
if (size > 0) {
|
|
content = malloc(size+1);
|
|
*content = '\0';
|
|
f = fopen(name, "r");
|
|
if (f != NULL) {
|
|
int len = fread(content, 1, size, f);
|
|
if (len < 0)
|
|
len = 0;
|
|
content[len] = '\0';
|
|
fclose(f);
|
|
}
|
|
}
|
|
else {
|
|
content = malloc(1);
|
|
*content = '\0';
|
|
}
|
|
return content;
|
|
}
|
|
|
|
int is_dir(const char *path)
|
|
{
|
|
char *tmp, *path_esc;
|
|
int ret;
|
|
|
|
require("sys/shell", 0, 1);
|
|
|
|
path_esc = shell_escape_dup(path);
|
|
tmp = malloc(strlen(path_esc) + 16);
|
|
sprintf(tmp, "cd %s", path_esc);
|
|
ret = run_shell(0, tmp, NULL);
|
|
free(tmp);
|
|
free(path_esc);
|
|
return !ret;
|
|
}
|
|
|
|
int is_file(const char *path)
|
|
{
|
|
return file_size(path) >= 0;
|
|
}
|
|
|
|
int exists(const char *path)
|
|
{
|
|
return is_file(path) || is_dir(path);
|
|
}
|
|
|
|
|
|
int exists_in(const char *dir, const char *file)
|
|
{
|
|
char *path;
|
|
int ret;
|
|
|
|
path = malloc(strlen(dir) + strlen(file) + 5);
|
|
sprintf(path, "%s/%s", dir, file);
|
|
ret = is_file(path) || is_dir(path);
|
|
free(path);
|
|
return ret;
|
|
}
|
|
|
|
const char *file_name_ptr(const char *path)
|
|
{
|
|
const char *s;
|
|
s = str_rchr((char *)path, '/');
|
|
if (s == NULL)
|
|
s = str_rchr((char *)path, '\\');
|
|
return s;
|
|
}
|
|
|
|
char *file_name(const char *path)
|
|
{
|
|
const char *s;
|
|
s = file_name_ptr(path);
|
|
if (s == NULL)
|
|
return strclone(path);
|
|
s++;
|
|
return strclone(s);
|
|
}
|
|
|
|
char *dir_name(const char *path)
|
|
{
|
|
char *s, *r;
|
|
s = strclone(path);
|
|
r = (char *)file_name_ptr(s);
|
|
if (r == NULL) {
|
|
free(s);
|
|
return strclone("");
|
|
}
|
|
*r = '\0';
|
|
return s;
|
|
}
|
|
|
|
int touch_file(const char *path)
|
|
{
|
|
FILE *f;
|
|
f = fopen(path, "a");
|
|
if (f == NULL)
|
|
return -1;
|
|
fclose(f);
|
|
return 0;
|
|
}
|