/*
* main.c
* Main entry point and global utility functions.
*
* Copyright (c) 2003 Christoph Pfisterer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "global.h"
#ifdef USE_MACOS_TYPE
#include <CoreServices/CoreServices.h>
#endif
/*
* local functions
*/
static void analyze_file(const char *filename);
static void print_kind(int filekind, u8 size, int size_known);
#ifdef USE_MACOS_TYPE
static void show_macos_type(const char *filename);
#endif
/*
* entry point
*/
int main(int argc, char *argv[])
{
int i;
/* argument check */
if (argc < 2) {
fprintf(stderr, "Usage: %s <device/file>...\n", PROGNAME);
return 1;
}
/* loop over filenames */
print_line(0, "");
for (i = 1; i < argc; i++) {
analyze_file(argv[i]);
print_line(0, "");
}
return 0;
}
/*
* Analyze one file
*/
static void analyze_file(const char *filename)
{
int fd, filekind;
u8 filesize;
struct stat sb;
char *reason;
SOURCE *s;
print_line(0, "--- %s", filename);
/* stat check */
if (stat(filename, &sb) < 0) {
errore("Can't stat %.300s", filename);
return;
}
filekind = 0;
filesize = 0;
reason = NULL;
if (S_ISREG(sb.st_mode)) {
filesize = sb.st_size;
print_kind(filekind, filesize, 1);
} else if (S_ISBLK(sb.st_mode))
filekind = 1;
else if (S_ISCHR(sb.st_mode))
filekind = 2;
else if (S_ISDIR(sb.st_mode))
reason = "Is a directory";
else if (S_ISFIFO(sb.st_mode))
reason = "Is a FIFO";
#ifdef S_ISSOCK
else if (S_ISSOCK(sb.st_mode))
reason = "Is a socket";
#endif
else
reason = "Is an unknown kind of special file";
if (reason != NULL) {
error("%.300s: %s", filename, reason);
return;
}
/* Mac OS type & creator code (if running on Mac OS X) */
#ifdef USE_MACOS_TYPE
if (filekind == 0)
show_macos_type(filename);
#endif
/* empty regular files need no further analysis */
if (filekind == 0 && filesize == 0)
return;
/* open for reading */
fd = open(filename, O_RDONLY);
if (fd < 0) {
errore("Can't open %.300s", filename);
return;
}
/* (try to) guard against TTY character devices */
if (filekind == 2) {
if (isatty(fd)) {
error("%.300s: Is a TTY device", filename);
return;
}
}
/* create a source */
s = init_file_source(fd, filekind);
/* tell the user what it is */
if (filekind != 0)
print_kind(filekind, s->size, s->size_known);
/* now analyze it */
analyze_source(s, 0);
/* finish it up */
close_source(s);
}
static void print_kind(int filekind, u8 size, int size_known)
{
char buf[256], *kindname;
if (filekind == 0)
kindname = "Regular file";
else if (filekind == 1)
kindname = "Block device";
else if (filekind == 2)
kindname = "Character device";
else
kindname = "Unknown kind";
if (size_known) {
format_size_verbose(buf, size);
print_line(0, "%s, size %s", kindname, buf);
} else {
print_line(0, "%s, unknown size", kindname);
}
}
/*
* Mac OS type & creator code
*/
#ifdef USE_MACOS_TYPE
static void show_macos_type(const char *filename)
{
int err;
FSRef ref;
FSCatalogInfo info;
FInfo *finfo;
err = FSPathMakeRef(filename, &ref, NULL);
if (err == 0) {
err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo,
&info, NULL, NULL, NULL);
}
if (err == 0) {
finfo = (FInfo *)(info.finderInfo);
if (finfo->fdType != 0 || finfo->fdCreator != 0) {
char typecode[5], creatorcode[5], s1[256], s2[256];
memcpy(typecode, &finfo->fdType, 4);
typecode[4] = 0;
format_ascii(typecode, s1);
memcpy(creatorcode, &finfo->fdCreator, 4);
creatorcode[4] = 0;
format_ascii(creatorcode, s2);
print_line(0, "Type code \"%s\", creator code \"%s\"",
s1, s2);
} else {
print_line(0, "No type and creator code");
}
}
if (err) {
print_line(0, "Type and creator code unknown (error %d)", err);
}
}
#endif
/* EOF */
syntax highlighted by Code2HTML, v. 0.9.1