detect.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1985 AT&T
* All Rights Reserved
*/
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8 */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include "wish.h"
#include "var_arrays.h"
#include "typetab.h"
#include "detabdefs.h"
#include "partabdefs.h"
#include "optabdefs.h"
#include "parse.h"
#include "sizes.h"
#define ACC_NOTSET 1
#define ACC_OKREAD 0
#define ACC_NOREAD -1
#define NULLSTR ""
/* #define PGSHFT 64 kludge to detect core files */
#define LOOKED_AT_OEH 1
#define LOOKED_AT_BYTES 2
static int Seen_non_printable;
static int Seen_eighth_bit;
static int Already_looked;
int Pathlen;
#ifndef WISH
void det_mail_in(), det_mail_out();
#endif
struct opt_entry *obj_to_parts();
static bool exist_heuristics();
static bool part_heuristics();
/* The heuristics program drives off of the detection table (defined in
* detab.c). It cycles through this table, executing heuristics commands
* as it goes. There are basically 4 kinds of heuristics:
*
* Heuristics based on object part names
* Heuristics based on magic numbers
* Heuristics based on user-defined functions
* Heuristics based on internal functions
*
* The most efficient method is part-names, the least efficient is
* user-defined functions since they require a fork().
* For this reason, it is probably best for user-defined functions to come
* last if possible.
*/
int
char *path;
char stray[][FILE_NAME_SIZ];
{ /* begin heuristics */
register int i;
long docmask = 0L;
bool is_directory, determined;
int heur;
int accessible;
for (i = 0; i < size; i++) {
if (stray[i][0] == '\0')
continue; /* already determined by other heuristics */
/* below, 3 is for: "/" & prefixes */
continue; /* ignore - path too big */
#ifdef _DEBUG
#endif
continue;
}
/* MUST be a directory to be check for exist_heuristics;
* Directories will ONLY be checked for exist_heuristics, part_-
* heuristics and shell and exec functions. (No magic or internal
*/
is_directory = TRUE;
else
else
docmask = 0L;
determined = FALSE;
Already_looked = 0;
case F_DPARTS:
if (is_directory == FALSE)
continue;
determined = TRUE;
break;
case F_PARTS:
determined = TRUE;
break;
case F_MAGIC:
if (is_directory == TRUE)
continue;
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
determined = TRUE;
break;
case F_SHELL:
case F_EXEC:
determined = TRUE;
break;
case F_INT:
if (is_directory == TRUE)
continue;
case IDF_ZLASC: /* zero length ascii */
/* file pathsize already tested at top of this fcn */
stray[i][0] = '\0';
determined = TRUE;
}
break;
case IDF_ASC:
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
if (! Seen_non_printable) {
/* file pathsize already tested at top of this fcn */
stray[i][0] = '\0';
determined = TRUE;
}
break;
case IDF_TRANS:
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
determined = TRUE;
}
break;
case IDF_CORE:
/* if a file is named "core" and it is at least 3 pages long
* and it is an even multiple of a page size, and it has at
* least one byte within the first five hundred with the
* eighth bit set, then it is probably a core file.
* >> This sounds nice but you can't do this with PGSHFT = 64
* >> which causes the code below to do nothing more than generate
* >> compiler warnings. you could replace PGSHFT with PNUMSHFT
* >> and may still get into trouble when memory management changes.
* >> since no one but the compiler has complained, I commented out
* >> the code. abs 9/15/88
*/
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
)
{
/* file pathsize already tested at top of this fcn */
stray[i][0] = '\0';
determined = TRUE;
}
break;
case IDF_ARCH:
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
/* file pathsize already tested at top of this fcn */
stray[i][0] = '\0';
determined = TRUE;
}
break;
case IDF_ENCRYPT:
if (accessible == ACC_NOTSET)
if (accessible == ACC_NOREAD)
break;
determined = TRUE;
}
break;
case IDF_UNKNOWN:
/* file pathsize already tested at top of this fcn */
stray[i][0] = '\0';
determined = TRUE;
break;
#ifndef WISH
case IDF_MAIL_IN:
determined = TRUE;
}
break;
case IDF_MAIL_OUT:
determined = TRUE;
}
break;
#endif
#ifdef _DEBUG
default:
#endif
}
}
}
}
return(0);
}
static bool
long mask;
char *odi;
{
register int i;
int part_offset, numparts;
char *base;
char *pattern;
char *part_construct();
int found[MAXOBJPARTS];
char *part_match();
/* get the parts table associated with objtype */
return(FALSE);
return(FALSE);
found[0] = 1;
for (i = 1; i < numparts; i++)
found[i] = -1;
for (i = 1; i < numparts; i++) {
/* if any part's path is > PATHSIZ, do not display it */
return(FALSE);
return(FALSE);
} else {
found[i] = 1;
}
}
/* file pathsize already tested in heuristics() - this uses "name" */
for (i = 1; i < numparts; i++) {
if (found[i] == 1)
/* file pathsize already tested when each part found */
}
return(TRUE);
}
static bool
char *path;
char stray[][FILE_NAME_SIZ];
char *objtype;
int index;
long mask;
char *odi;
void (*info_func)();
{
register int i, j;
int found[MAXOBJPARTS];
int part_offset, numparts;
char *dname;
char *part_match();
/* get the parts table associated with objtype */
return(FALSE);
for (i = 0; i < numparts; i++)
found[i] = -1;
/* look for the entry index in the table, in reverse order since
* the more restrictive names are at the end (for example, the first
* parts template is often unrestricted).
*/
for (i = numparts-1; i >= 0; i--)
break;
}
if (!p) /* was not found */
return(FALSE);
/* if any part's path is > PATHSIZ, do not display it */
if ((found[i] != -1) &&
return(FALSE);
/* scan through the rest of the parts, looking in the stray
* array for each one. If a required part is ever not found,
* or if the name is > PATHSIZ,
* then immediately return FALSE.
*/
for (i = 0; i < numparts; i++) {
/* don't look for an already found part */
if (found[i] != -1)
continue;
for (j = 0; j < size; j++) {
continue;
found[i] = j;
break;
}
}
/* if a required part is not found, then return FALSE */
return(FALSE);
/* if any part's path is > PATHSIZ, do not display it */
if ((found[i] != -1) &&
return(FALSE);
}
/* at this point, we should have all the parts, so we will go
* through the found array and make entries for each part.
*/
j = 0;
while (found[j] == -1)
j++;
} else {
else
}
/* file pathsize already tested when each part found */
for (i = j+1; i < numparts; i++) {
if (found[i] != -1) {
/* file pathsize already tested when each part found */
}
}
return(TRUE);
}
static int
{
register char *p;
register int numread;
register int fd;
if (Already_looked & LOOKED_AT_BYTES)
return;
return;
if (!isascii(*p))
}
}
static int
long mask;
char *odi;
long *offsets;
char *bytes;
{
register int i;
/* file pathsize already tested in heuristics() */
return(0);
for (i = 0; offsets[i] != -1; i++) {
/* if the next offset is equal to the previous plus one, no need
* to seek
*/
return(0);
}
}
return(0);
}
}
name[0] = 0;
return(1);
}
/* currently unimplemented */
static int
{
return(0);
}
static int
long defmask;
char *defodi;
{
char fullpath_or_odi[PATHSIZ];
/* file pathsize already tested in heuristics() */
if (look_at_oeh(fullpath_or_odi) != 0) {
return(0);
}
if (!objtype) { /* any encrypted object */
else
return (0);
}
/* reuse fullpath_or_odi variable */
return(1);
}
int
char *path;
{
static int oeh_retcode;
if (Already_looked & LOOKED_AT_OEH)
return(oeh_retcode);
#ifdef WISH
#else
#endif
#ifdef _DEBUG
#endif
return(oeh_retcode);
}