Kjetil's Information Center: A Blog About My Projects

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;
}
          


Topic: Scripts and Code, by Kjetil @ 02/04-2014, Article Link