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);
121 /**********************************************************************/
122 /* Returns malloced string containing concatenation of two */
124 /**********************************************************************/
125 char *stradd(const char *s1,const char *s2)
127 res=malloc(strlen(s1)+strlen(s2)+1);
129 fprintf (stderr,"Out of memory!");
139 * In DOS, argv[0] contain full path to the program, and it is a custom
140 * to keep configuration files in same directory as program itself
143 char *exe_dir(void) {
144 static char pathbuf[PATH_BUF_SIZE];
146 strcpy(pathbuf,_argv[0]); /* DOS ensures, that our exe path is no
147 longer than PATH_BUF_SIZE*/
148 q=strrchr(pathbuf,DIR_SEP);
156 char *add_exe_path(const char *name) {
157 static char path[PATH_BUF_SIZE];
158 char *mypath=exe_dir();
159 /* No snprintf in Turbo C 2.0 library, so just check by hand
160 and exit if something goes wrong */
161 if (strchr(name,'%')) {
162 /* there is substitution */
163 if (strlen(name)-1+strlen(mypath)>=PATH_BUF_SIZE) {
164 fprintf(stderr,"Invalid config file. file name \"%s\" too long "
165 "after substitution\n",name);
168 sprintf(path,name,exe_dir());
175 /*********************************************************************/
176 /* Prints out list of available charsets, i.e. names without extension *
177 * of all .txt files in the charset path + internally-supported utf-8 *
178 ************************************************************************/
180 void list_charsets(void) {
183 char path_buf[PATH_BUF_SIZE];
184 char dir_sep[2]={DIR_SEP,0};
187 struct ffblk ffblock;
191 int count,glob_flags=GLOB_ERR;
193 memset(&glob_buf,0,sizeof(glob_t));
195 for (p=charset_path;p;p=(q?(q+1):NULL)) {
196 q=strchr(p,LIST_SEP);
198 if (q-p>=PATH_BUF_SIZE) {
199 /* Oops, dir name too long, perhabs broken config file */
202 strncpy(path_buf,p,q-p);
205 if (strlen(p)>=PATH_BUF_SIZE) continue;
208 /* Empty list element means current directory */
214 strcpy(path_buf,add_exe_path(path_buf)); /* safe, becouse
215 add_exe_path knows about PATH_BUF_SIZE */
218 strcat(path_buf,dir_sep); /* always one char */
219 if (strlen(path_buf)+6>=PATH_BUF_SIZE)
220 continue; /* Ignore too deeply nested directories */
221 strcat(path_buf,"*.txt");
223 res=findfirst(path_buf,&ffblock,FA_RDONLY | FA_HIDDEN | FA_ARCH);
225 printf("Available charsets:\n");
227 char name[12],*src,*dest;
230 for (dest=name,src=ffblock.ff_name;*src && *src !='.';dest++,src++)
232 *dest++=(col<5)?'\t':'\n';
236 res=findnext(&ffblock);
239 switch (glob(path_buf,glob_flags,NULL,&glob_buf)) {
249 glob_flags|=GLOB_APPEND;
253 fputs("utf-8\n",stdout);
255 count=0;printf("Available charsets:");
256 for (ptr=glob_buf.gl_pathv;*ptr;ptr++) {
257 printf("%c",(count++)%5?'\t':'\n');
258 p=strrchr(*ptr,dir_sep[0]);
261 if ((q=strchr(p,'.'))) *q=0;
264 printf("%c",(count++)%5?'\t':'\n');
265 fputs("utf-8",stdout);