2 Copyright 1998-2003 Victor Wagner
3 Copyright 2003 Alex Ott
4 This file is released under the GPL. Details can be
5 found in the file COPYING accompanying this distribution.
16 #if defined(MSDOS) && !defined(__MSDOS__)
19 #if defined(__MSDOS__) || defined(_WIN32)
27 /************************************************************************/
28 /* Copies component of string starting with p and ending one char */
29 /* before q into path_buf, expanding ~ if neccessary */
30 /************************************************************************/
31 int prepare_path_buf(char *path_buf, const char *start, const char *end) {
32 if (*start == '~' && start[1] == DIR_SEP) {
33 char *home=getenv("HOME");
36 if (end-start>PATH_BUF_SIZE) return 0;
37 strncpy(path_buf,start,end-start);
38 path_buf[end-start]=0;
41 if (l+(end-start)>PATH_BUF_SIZE) return 0;
42 strcpy(path_buf,home);
43 strncpy(path_buf+l,start,end-start);
44 path_buf[end-start+l]=0;
47 if (end-start>PATH_BUF_SIZE) return 0;
48 strncpy(path_buf,start,end-start);
49 path_buf[end-start]=0;
51 /* Empty list element means current directory */
57 strcpy(path_buf,add_exe_path(path_buf)); /* safe, becouse
58 add_exe_path knows about PATH_BUF_SIZE */
64 /************************************************************************/
65 /* Searches for file name in specified list of directories. Sets */
66 /* Returns dynamically allocated full path or NULL. if nothing */
67 /* appropriate Expects name to be dynamically allocated and frees it */
68 /************************************************************************/
69 char *find_file(char *name, const char *path)
72 char path_buf[PATH_BUF_SIZE];
73 char dir_sep[2]={DIR_SEP,0};
74 for (p=path;p;p=(q?(q+1):NULL)) {
77 if (!prepare_path_buf(path_buf,p,q)) continue;
79 if (!prepare_path_buf(path_buf,p,p+strlen(p))) continue;
81 strcat(path_buf,dir_sep); /* always one char */
82 if (strlen(path_buf)+strlen(name)>=PATH_BUF_SIZE)
83 continue; /* Ignore too deeply nested directories */
84 strcat(path_buf,name);
85 if (access(path_buf,0)==0) {
87 return strdup(path_buf);
90 /* if we are here, nothing found */
95 /************************************************************************/
96 /* Searches for charset with given name and put pointer to malloced copy*/
97 /* of its name into first arg if found. Otherwise leaves first arg */
98 /* unchanged. Returns non-zero on success */
99 /************************************************************************/
100 int check_charset(char **filename,const char *charset) {
102 if (!strncmp(charset,"utf-8",6)) {
103 *filename=strdup("utf-8");
106 tmppath=find_file(stradd(charset,CHARSET_EXT),charset_path);
107 /* Some compilers evalate both arguments of && before
108 applying, so let's not use && as in the shell */
111 *filename=strdup(charset);
119 /**********************************************************************/
120 /* Returns malloced string containing concatenation of two */
122 /**********************************************************************/
123 char *stradd(const char *s1,const char *s2)
125 res=malloc(strlen(s1)+strlen(s2)+1);
127 fprintf (stderr,"Out of memory!");
137 * In DOS, argv[0] contain full path to the program, and it is a custom
138 * to keep configuration files in same directory as program itself
141 char *exe_dir(void) {
142 static char pathbuf[PATH_BUF_SIZE];
144 strcpy(pathbuf,_argv[0]); /* DOS ensures, that our exe path is no
145 longer than PATH_BUF_SIZE*/
146 q=strrchr(pathbuf,DIR_SEP);
154 char *add_exe_path(const char *name) {
155 static char path[PATH_BUF_SIZE];
156 char *mypath=exe_dir();
157 /* No snprintf in Turbo C 2.0 library, so just check by hand
158 and exit if something goes wrong */
159 if (strchr(name,'%')) {
160 /* there is substitution */
161 if (strlen(name)-1+strlen(mypath)>=PATH_BUF_SIZE) {
162 fprintf(stderr,"Invalid config file. file name \"%s\" too long "
163 "after substitution\n",name);
166 sprintf(path,name,exe_dir());
173 /*********************************************************************/
174 /* Prints out list of available charsets, i.e. names without extension *
175 * of all .txt files in the charset path + internally-supported utf-8 *
176 ************************************************************************/
178 void list_charsets(void) {
181 char path_buf[PATH_BUF_SIZE];
182 char dir_sep[2]={DIR_SEP,0};
184 struct ffblk ffblock;
188 int count,glob_flags=GLOB_ERR;
191 for (p=charset_path;p;p=(q?(q+1):NULL)) {
192 q=strchr(p,LIST_SEP);
194 if (q-p>=PATH_BUF_SIZE) {
195 /* Oops, dir name too long, perhabs broken config file */
198 strncpy(path_buf,p,q-p);
201 if (strlen(p)>=PATH_BUF_SIZE) continue;
204 /* Empty list element means current directory */
210 strcpy(path_buf,add_exe_path(path_buf)); /* safe, becouse
211 add_exe_path knows about PATH_BUF_SIZE */
214 strcat(path_buf,dir_sep); /* always one char */
215 if (strlen(path_buf)+6>=PATH_BUF_SIZE)
216 continue; /* Ignore too deeply nested directories */
217 strcat(path_buf,"*.txt");
219 res=findfirst(path_buf,&ffblock,FA_RDONLY | FA_HIDDEN | FA_ARCH);
221 printf("Available charsets:\n");
223 char name[12],*src,*dest;
226 for (dest=name,src=ffblock.ff_name;*src && *src !='.';dest++,src++)
228 *dest++=(col<5)?'\t':'\n';
232 res=findnext(&ffblock);
235 switch (glob(path_buf,glob_flags,NULL,&glob_buf)) {
245 glob_flags|=GLOB_APPEND;
249 fputs("utf-8\n",stdout);
251 count=0;printf("Available charsets:");
252 for (ptr=glob_buf.gl_pathv;*ptr;ptr++) {
253 printf("%c",(count++)%5?'\t':'\n');
254 p=strrchr(*ptr,dir_sep[0]);
257 if ((q=strchr(p,'.'))) *q=0;
260 printf("%c",(count++)%5?'\t':'\n');
261 fputs("utf-8",stdout);