2 * Copyright (c) 2014 by David I. Bell
3 * Permission is granted to use, distribute, or modify this source,
4 * provided that this copyright notice remains intact.
6 * The "file" built-in command.
11 #include <sys/types.h>
17 static const char * checkFile(const char * name);
21 do_file(int argc, const char ** argv)
33 info = checkFile(name);
36 info = "No information available";
38 printf("%s: %s\n", name, info);
46 * Examine the specified file and return a static string which
47 * describes the file type. Returns NULL on a failure.
50 checkFile(const char * name)
61 static char info[1024];
66 if (lstat(name, &statBuf) < 0)
69 return "non-existent";
71 sprintf(cp, "stat failed: %s", strerror(errno));
77 * Check the file type.
79 mode = statBuf.st_mode;
85 return "character device";
88 return "block device";
95 return "symbolic link";
104 * If the file is not a regular file mention that.
108 sprintf(cp, "unknown mode 0x%x, \n", mode);
114 * Check for an executable file.
116 if ((mode & (S_IEXEC | S_IXGRP | S_IXOTH)) != 0)
118 strcpy(cp, "executable, ");
124 * The file is a normal file.
125 * Open it if we can and read in the first block.
127 fd = open(name, O_RDONLY);
131 sprintf(cp, "unreadable: %s", strerror(errno));
136 cc = read(fd, data, sizeof(data));
140 sprintf(cp, "read error: %s", strerror(errno));
150 * Check for an empty file.
154 strcpy(cp, "empty file");
160 * Check for a script file.
162 if ((cc > 2) && (data[0] == '#') && (data[1] == '!'))
167 data[sizeof(data) - 1] = '\0';
171 while (*begin == ' ')
176 while (*end && (*end != ' ') && (*end != '\n'))
181 sprintf(cp, "script for \"%s\"", begin);
187 * Check for special binary data types.
189 if ((data[0] == '\037') && (data[1] == '\235'))
190 return "compressed file";
192 if ((data[0] == '\037') && (data[1] == '\213'))
195 if ((data[0] == '\177') && (memcmp(&data[1], "ELF", 3) == 0))
197 strcpy(cp, "ELF program");
203 * Check for binary data.
207 for (i = 0; i < cc; i++)
211 if ((ch == '\n') || (ch == '\t'))
214 if (isspace(ch) || isprint(ch))
222 strcpy(cp, "binary");
228 * It is just a text file.
230 strcpy(cp, "text file");