True Filename Listing
Here is a special tool I made to view the true names of files. A filename with characters other than ASCII (or ISO-8859) just shows up as question marks if you use the regular "ls" command. This is an alternative command that displays the filenames using a hex encoding, if the output is a TTY (terminal). If the output is redirected to a file, the true character values will be dumped.
Here is the source code, enjoy:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
static void list(char *dirname)
{
DIR *dir;
struct dirent *file;
int i, len, longest;
dir = opendir(dirname);
if (dir == NULL)
return;
longest = 0;
while ((file = readdir(dir)) != NULL) {
len = strlen(file->d_name);
if (len > longest)
longest = len;
}
rewinddir(dir);
while ((file = readdir(dir)) != NULL) {
if (isatty(STDOUT_FILENO)) {
/* Printable name */
for (i = 0; file->d_name[i] != '\0'; i++) {
if (isprint(file->d_name[i])) {
printf("%c", file->d_name[i]);
} else {
printf("?");
}
}
/* Padding */
while (i < longest) {
printf(" ");
i++;
}
printf(" ");
/* Hex name */
for (i = 0; file->d_name[i] != '\0'; i++) {
printf("%02x", (unsigned char)file->d_name[i]);
}
printf("\n");
} else {
/* Raw output */
for (i = 0; file->d_name[i] != '\0'; i++) {
printf("%c", file->d_name[i]);
}
printf("\n");
}
}
closedir(dir);
}
int main(int argc, char *argv[])
{
int i;
struct stat st;
if (argc > 1) {
for (i = 1; i < argc; i++) {
if (stat(argv[i], &st) == 0) {
if (S_ISDIR(st.st_mode)) {
if (i > 1)
printf("\n");
printf("%s:\n", argv[i]);
list(argv[i]);
}
}
}
} else {
list(".");
}
return 0;
}