1/* by tino@augsburg.net
2 */
3
4#include <stdio.h>
5#include <string.h>
6
7#include <dirent.h>
8
9unsigned char
10test(void)
11{
12  DIR		*dir;
13  struct dirent	*dp;
14  unsigned char	c;
15
16  if ((dir=opendir("."))==0)
17    {
18      perror("open .");
19      return 0;
20    }
21  c	= 0;
22  while ((dp=readdir(dir))!=0)
23    {
24      size_t len;
25
26      len	= strlen(dp->d_name);
27      if (len<4)
28	continue;
29      if (strcmp(dp->d_name+len-4, ".TST"))
30	continue;
31      if (len!=5)
32	{
33	  fprintf(stderr, "warning: %s\n", dp->d_name);
34	  printf(" length");
35	  continue;
36	}
37      if (c)
38	printf(" double%d\n", c);
39      c	= dp->d_name[0];
40    }
41  if (closedir(dir))
42    perror("close .");
43  return c;
44}
45
46int
47main(void)
48{
49  char		name[256];
50  unsigned char	map[256], upper[256], lower[256];
51  int		i, j, c;
52  FILE		*fd;
53
54  if (test())
55    {
56      printf("There are *.TST files, please remove\n");
57      return 0;
58    }
59  for (i=0; ++i<256; )
60    {
61      lower[i]	= i;
62      upper[i]	= 0;
63    }
64  for (i=256; --i; )
65    {
66      map[i]	= i;
67      strcpy(name, "..TST");
68      name[0]	= i;
69      printf("%d:", i);
70      if ((fd=fopen(name, "w"))==0)
71	printf(" open");
72      else
73	fclose(fd);
74      c	= test();
75      if (unlink(name))
76	printf(" unlink");
77      if (c==i)
78	printf(" ok");
79      else
80	printf(" %d", c);
81      printf("\n");
82      if (c!=i)
83	{
84	  upper[c]++;
85	  lower[c]	= i;
86        }
87      map[i]	= c;
88    }
89
90  /* Uppercase characters are detected above on:
91   * The character is mapped to itself and there is a
92   * character which maps to it.
93   * Lowercase characters are the lowest character pointing to another one.
94   * Else it is a one way character.
95   *
96   * For this reason we have to process the list
97   * 1) for 'one way' characters
98   *	'one way' is something which is no upper and no lower character.
99   *	This is an awful, crude and ugly hack due to missing Samba support.
100   * 2) for true uppercase/lowercase characters
101   * 3) for standalone characters
102   * Note that there might be characters which do not fall into 1 to 3.
103   */
104  printf("\n   valid chars =");
105  for (i=0; ++i<256; )
106    if (map[i] && map[i]!=i && lower[map[i]]!=i)
107      {
108	if (!upper[i])
109	  printf(" %d:%d %d:%d %d:%d",					/*1*/
110		 map[i], i, i, map[i], map[i], map[i]);
111	else
112	  fprintf(stderr, "ignoring map %d->%d because of %d->%d\n",
113		  lower[i], i, i, map[i]);
114      }
115  for (i=0; ++i<256; )
116    if (map[i] && map[i]==i)
117      if (upper[i])
118	printf(" %d:%d", lower[i], i);					/*2*/
119      else
120	printf(" %d", i);						/*3*/
121  printf("\n");
122  return 0;
123}
124