/*
* Copyright (c) 1997, 1998, 1999, 2000, 2006
* Tama Communications Corporation
*
* This file is part of GNU GLOBAL.
*
* 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 3 of the License, 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, see .
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#ifdef HAVE_STRING_H
#include
#else
#include
#endif
#ifdef HAVE_UNISTD_H
#include
#endif
#ifdef HAVE_FCNTL_H
#include
#else
#include
#endif
#include "locatestring.h"
#include "die.h"
#include "test.h"
/*
* Decide whether or not the path is binary file.
*
* i) path
* r) 0: is not binary, 1: is binary
*/
static int
is_binary(const char *path)
{
int ip;
char buf[32];
int i, c, size;
ip = open(path, O_RDONLY);
if (ip < 0)
die("cannot open file '%s' in read mode.", path);
size = read(ip, buf, sizeof(buf));
close(ip);
if (size < 0)
return 1;
if (size >= 7 && locatestring(buf, "!", MATCH_AT_FIRST))
return 1;
for (i = 0; i < size; i++) {
c = (unsigned char)buf[i];
if (c == 0 || c > 127)
return 1;
}
return 0;
}
/*
* test:
*
* i) flags file flags
*
* "f" [ -f path ]
* "d" [ -d path ]
* "r" [ -r path ]
* "s" [ -s path ]
* "w" [ -w path ]
* "x" [ -x path ]
* "b" [ -b path ]
*
* i) path path
* if NULL then previous path.
* r) 0: no, 1: ok
*
* You can specify more than one character. It assumed 'AND' test.
*/
int
test(const char *flags, const char *path)
{
static struct stat sb;
int c;
if (path != NULL)
if (stat(path, &sb) < 0)
return 0;
while ((c = *flags++) != 0) {
switch (c) {
case 'b':
if (!is_binary(path))
return 0;
break;
case 'f':
if (!S_ISREG(sb.st_mode))
return 0;
break;
case 'd':
if (!S_ISDIR(sb.st_mode))
return 0;
break;
case 'r':
if (access(path, R_OK) < 0)
return 0;
break;
case 's':
if (sb.st_size == 0)
return 0;
break;
case 'w':
if (access(path, W_OK) < 0)
return 0;
break;
case 'x':
#ifdef _WIN32
/* Look at file extension to determine executability */
if (strlen(path) < 5)
return 0;
if (!S_ISREG(sb.st_mode))
return 0;
if (!locatestring(path, ".exe", MATCH_AT_LAST|IGNORE_CASE) &&
!locatestring(path, ".com", MATCH_AT_LAST|IGNORE_CASE) &&
!locatestring(path, ".bat", MATCH_AT_LAST|IGNORE_CASE))
return 0;
#else
if (access(path, X_OK) < 0)
return 0;
#endif
break;
default:
break;
}
}
return 1;
}
/*
* filesize: get file size in bytes.
*
* i) path path of file
* r) != -1: file size
* == -1: file not found
*/
int
filesize(const char *path)
{
struct stat sb;
if (stat(path, &sb) < 0)
return -1;
return sb.st_size;
}