Cover V05, I02
Article
Listing 1

feb96.tar


Listing 1: isascii.c

/* isascii.c -- Copyright 1995 by Steven G. Isaacson */

#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BUFSIZE 2048
#define MAX_FN 256

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

char *help[] = {
"-e echo filename even if only one file",
"-F [filename] file containing list of filenames",
"-v reverse isascii() check",
"-  read filenames from stdin",
"",
"isascii checks for ascii characters in the specified file(s).",
"If non-ascii characters are found false(1) is returned,",
"otherwise true(0) is returned.  When only one file is specified",
"there is no output unless the echo flag is used.",
"",
"If stdin, a list of files, or if more than one file is specified",
"on the command-line, then the ascii files are echoed and non-ascii",
"files are not. Exit status is always true.",
'\0' };

char *usage_str="Usage:  isascii [-args] [filename(s)|-]";

int reverse=0; /* global for -v flag */

main(argc, argv)
int argc;
char *argv[];
{
int i;
extern int optind;
extern char *optarg;
char *options="v?heF:";
int c, errflg=0, echo=0;
char stdinfn[MAX_FN];
FILE *stdinfp;

stdinfn[0] = '\0';

if (argc == 1) {
fprintf(stderr, "%s\n", usage_str);
exit(1);
}

while ((c=getopt(argc, argv, options)) != EOF) {

switch (c) {

case 'F':
strcpy(stdinfn, optarg);
break;

case 'v':
reverse=1;
break;

case 'e':
echo=1;
break;

case '?':
case 'h':
default:
errflg++;
break;
}

if (errflg) {
show_help();
exit(0);
}
}

if (stdinfn[0]) {
/* input is coming from a file */

if ((stdinfp = fopen(stdinfn, "r")) == NULL) {
fprintf ( stderr,
"*** Error: could not open: %s\n", stdinfn);
exit(2);
}

file_or_stdin(stdinfp);
}
else {
/* input from command-line or stdin */

for (i=optind; i < argc; i++) {

if ( argv[i][0] == '-' ) {
file_or_stdin(stdin);
continue;
}

if (i != argc - 1)
is_ascii(argv[i], TRUE);
else
exit(is_ascii(argv[i], echo));
}
}
exit(0);
}

/* ================================================= */
/* show help page                                    */

show_help()
{
int i;

fprintf(stderr, "%s\n", usage_str);
for (i=0; help[i]; i++)
fprintf(stderr, "  %s\n", help[i]);

fprintf(stderr, "\n");
fflush(stderr);
}

/* ================================================= */
/* get the list of files from a file or stdin.       */

file_or_stdin(fp)
FILE *fp;
{
char buf[MAX_FN], *retval;

/* for each name in the list, call is_ascii() */
while (
(retval=fgets(buf, MAX_FN, fp)) != (char *)EOF &&
retval != NULL ) {
buf[strlen(buf) - 1] = '\0';
is_ascii(buf, TRUE);
}
}

/* ================================================= */
/* read the file looking for non-ascii characters    */

int is_ascii(pfn, echo)
char *pfn;
int echo;
{
int fd, i, n;
char buf[BUFSIZE];

if ( (fd=open(pfn, O_RDONLY|O_NDELAY)) == -1 ) {
fprintf(stderr,
"Error: could not open: %s\n", pfn);
fflush(stderr);
return(1);
}

switch (reverse) {
case 0:
/*
* normal case is not reverse.  if non-ascii
* char found then test has failed
*/
while ((n=read(fd, buf, sizeof(buf))) > 0 ) {
for (i=0; i < n; i++) {
if (!isascii((int)buf[i]) && buf[i] != EOF) {
close(fd);
return(1); /* failure */
}
}
}
if (echo) printf("%s\n", pfn);

case 1:
/*
* -v flag was used.  Now if we find a non-ascii
* char the test is a success.
*/
while ((n=read(fd, buf, sizeof(buf))) > 0 ) {
for (i=0; i < n; i++) {
if (!isascii((int)buf[i]) &&
buf[i] != EOF) {
if (echo) printf("%s\n", pfn);
close(fd);
return(0); /* success */
}
}
}
}

close(fd); /* we're at EOF */
/*
* return success, unless -v was used, in which case
* we failed to find non-ascii values
*/
return(reverse);
}

/* End of File */