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 if (tmppath&& *tmppath) {
108 *filename=strdup(charset);
115 /**********************************************************************/
116 /* Returns malloced string containing concatenation of two */
118 /**********************************************************************/
119 char *stradd(const char *s1,const char *s2)
121 res=malloc(strlen(s1)+strlen(s2)+1);
123 fprintf (stderr,"Out of memory!");
133 * In DOS, argv[0] contain full path to the program, and it is a custom
134 * to keep configuration files in same directory as program itself
137 char *exe_dir(void) {
138 static char pathbuf[PATH_BUF_SIZE];
140 strcpy(pathbuf,_argv[0]); /* DOS ensures, that our exe path is no
141 longer than PATH_BUF_SIZE*/
142 q=strrchr(pathbuf,DIR_SEP);
150 char *add_exe_path(const char *name) {
151 static char path[PATH_BUF_SIZE];
152 char *mypath=exe_dir();
153 /* No snprintf in Turbo C 2.0 library, so just check by hand
154 and exit if something goes wrong */
155 if (strchr(name,'%')) {
156 /* there is substitution */
157 if (strlen(name)-1+strlen(mypath)>=PATH_BUF_SIZE) {
158 fprintf(stderr,"Invalid config file. file name \"%s\" too long "
159 "after substitution\n",name);
162 sprintf(path,name,exe_dir());
169 /*********************************************************************/
170 /* Prints out list of available charsets, i.e. names without extension *
171 * of all .txt files in the charset path + internally-supported utf-8 *
172 ************************************************************************/
174 void list_charsets(void) {
177 char path_buf[PATH_BUF_SIZE];
178 char dir_sep[2]={DIR_SEP,0};
180 struct ffblk ffblock;
184 int count,glob_flags=GLOB_ERR;
187 for (p=charset_path;p;p=(q?(q+1):NULL)) {
188 q=strchr(p,LIST_SEP);
190 if (q-p>=PATH_BUF_SIZE) {
191 /* Oops, dir name too long, perhabs broken config file */
194 strncpy(path_buf,p,q-p);
197 if (strlen(p)>=PATH_BUF_SIZE) continue;
200 /* Empty list element means current directory */
206 strcpy(path_buf,add_exe_path(path_buf)); /* safe, becouse
207 add_exe_path knows about PATH_BUF_SIZE */
210 strcat(path_buf,dir_sep); /* always one char */
211 if (strlen(path_buf)+6>=PATH_BUF_SIZE)
212 continue; /* Ignore too deeply nested directories */
213 strcat(path_buf,"*.txt");
215 res=findfirst(path_buf,&ffblock,FA_RDONLY | FA_HIDDEN | FA_ARCH);
217 printf("Available charsets:\n");
219 char name[12],*src,*dest;
222 for (dest=name,src=ffblock.ff_name;*src && *src !='.';dest++,src++)
224 *dest++=(col<5)?'\t':'\n';
228 res=findnext(&ffblock);
231 switch (glob(path_buf,glob_flags,NULL,&glob_buf)) {
241 glob_flags|=GLOB_APPEND;
245 fputs("utf-8\n",stdout);
247 count=0;printf("Available charsets:");
248 for (ptr=glob_buf.gl_pathv;*ptr;ptr++) {
249 printf("%c",(count++)%5?'\t':'\n');
250 p=strrchr(*ptr,dir_sep[0]);
253 if ((q=strchr(p,'.'))) *q=0;
256 printf("%c",(count++)%5?'\t':'\n');
257 fputs("utf-8",stdout);