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+1) {
78 if (!prepare_path_buf(path_buf,p,q)) continue;
81 if (!prepare_path_buf(path_buf,p,p+strlen(p))) continue;
83 strcat(path_buf,dir_sep); /* always one char */
84 if (strlen(path_buf)+strlen(name)>=PATH_BUF_SIZE)
85 continue; /* Ignore too deeply nested directories */
86 strcat(path_buf,name);
87 if (access(path_buf,0)==0) {
89 return strdup(path_buf);
92 /* if we are here, nothing found */
97 /************************************************************************/
98 /* Searches for charset with given name and put pointer to malloced copy*/
99 /* of its name into first arg if found. Otherwise leaves first arg */
100 /* unchanged. Returns non-zero on success */
101 /************************************************************************/
102 int check_charset(char **filename,const char *charset) {
104 if (!strncmp(charset,"utf-8",6)) {
105 *filename=strdup("utf-8");
108 tmppath=find_file(stradd(charset,CHARSET_EXT),charset_path);
109 if (tmppath&& *tmppath) {
110 *filename=strdup(charset);
117 /**********************************************************************/
118 /* Returns malloced string containing concatenation of two */
120 /**********************************************************************/
121 char *stradd(const char *s1,const char *s2)
123 res=malloc(strlen(s1)+strlen(s2)+1);
125 fprintf (stderr,"Out of memory!");
135 * In DOS, argv[0] contain full path to the program, and it is a custom
136 * to keep configuration files in same directory as program itself
139 char *exe_dir(void) {
140 static char pathbuf[PATH_BUF_SIZE];
142 strcpy(pathbuf,_argv[0]); /* DOS ensures, that our exe path is no
143 longer than PATH_BUF_SIZE*/
144 q=strrchr(pathbuf,DIR_SEP);
152 char *add_exe_path(const char *name) {
153 static char path[PATH_BUF_SIZE];
154 char *mypath=exe_dir();
155 /* No snprintf in Turbo C 2.0 library, so just check by hand
156 and exit if something goes wrong */
157 if (strchr(name,'%')) {
158 /* there is substitution */
159 if (strlen(name)-1+strlen(mypath)>=PATH_BUF_SIZE) {
160 fprintf(stderr,"Invalid config file. file name \"%s\" too long "
161 "after substitution\n",name);
164 sprintf(path,name,exe_dir());
171 /*********************************************************************/
172 /* Prints out list of available charsets, i.e. names without extension *
173 * of all .txt files in the charset path + internally-supported utf-8 *
174 ************************************************************************/
176 void list_charsets(void) {
179 char path_buf[PATH_BUF_SIZE];
180 char dir_sep[2]={DIR_SEP,0};
182 struct ffblk ffblock;
186 int count,glob_flags=GLOB_ERR;
189 for (p=charset_path;p;p=q+1) {
190 q=strchr(p,LIST_SEP);
193 if (q-p>=PATH_BUF_SIZE) {
194 /* Oops, dir name too long, perhabs broken config file */
197 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);