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 (charset == NULL ) {
105 if (!strncmp(charset,"utf-8",6)) {
106 *filename=strdup("utf-8");
109 tmppath=find_file(stradd(charset,CHARSET_EXT),charset_path);
110 if (tmppath && *tmppath) {
111 *filename=strdup(charset);
118 /**********************************************************************/
119 /* Returns malloced string containing concatenation of two */
121 /**********************************************************************/
122 char *stradd(const char *s1,const char *s2)
124 res=malloc(strlen(s1)+strlen(s2)+1);
126 fprintf (stderr,"Out of memory!");
136 * In DOS, argv[0] contain full path to the program, and it is a custom
137 * to keep configuration files in same directory as program itself
140 char *exe_dir(void) {
141 static char pathbuf[PATH_BUF_SIZE];
143 strcpy(pathbuf,_argv[0]); /* DOS ensures, that our exe path is no
144 longer than PATH_BUF_SIZE*/
145 q=strrchr(pathbuf,DIR_SEP);
153 char *add_exe_path(const char *name) {
154 static char path[PATH_BUF_SIZE];
155 char *mypath=exe_dir();
156 /* No snprintf in Turbo C 2.0 library, so just check by hand
157 and exit if something goes wrong */
158 if (strchr(name,'%')) {
159 /* there is substitution */
160 if (strlen(name)-1+strlen(mypath)>=PATH_BUF_SIZE) {
161 fprintf(stderr,"Invalid config file. file name \"%s\" too long "
162 "after substitution\n",name);
165 sprintf(path,name,exe_dir());
172 /*********************************************************************/
173 /* Prints out list of available charsets, i.e. names without extension *
174 * of all .txt files in the charset path + internally-supported utf-8 *
175 ************************************************************************/
177 void list_charsets(void) {
180 char path_buf[PATH_BUF_SIZE];
181 char dir_sep[2]={DIR_SEP,0};
184 struct ffblk ffblock;
188 int count,glob_flags=GLOB_ERR;
190 memset(&glob_buf,0,sizeof(glob_t));
192 for (p=charset_path;p;p=(q?(q+1):NULL)) {
193 q=strchr(p,LIST_SEP);
195 if (q-p>=PATH_BUF_SIZE) {
196 /* Oops, dir name too long, perhabs broken config file */
199 strncpy(path_buf,p,q-p);
202 if (strlen(p)>=PATH_BUF_SIZE) continue;
205 /* Empty list element means current directory */
211 strcpy(path_buf,add_exe_path(path_buf)); /* safe, becouse
212 add_exe_path knows about PATH_BUF_SIZE */
215 strcat(path_buf,dir_sep); /* always one char */
216 if (strlen(path_buf)+6>=PATH_BUF_SIZE)
217 continue; /* Ignore too deeply nested directories */
218 strcat(path_buf,"*.txt");
220 res=findfirst(path_buf,&ffblock,FA_RDONLY | FA_HIDDEN | FA_ARCH);
222 printf("Available charsets:\n");
224 char name[12],*src,*dest;
227 for (dest=name,src=ffblock.ff_name;*src && *src !='.';dest++,src++)
229 *dest++=(col<5)?'\t':'\n';
233 res=findnext(&ffblock);
236 switch (glob(path_buf,glob_flags,NULL,&glob_buf)) {
246 glob_flags|=GLOB_APPEND;
250 fputs("utf-8\n",stdout);
252 count=0;printf("Available charsets:");
253 for (ptr=glob_buf.gl_pathv;*ptr;ptr++) {
254 printf("%c",(count++)%5?'\t':'\n');
255 p=strrchr(*ptr,dir_sep[0]);
258 if ((q=strchr(p,'.'))) *q=0;
261 printf("%c",(count++)%5?'\t':'\n');
262 fputs("utf-8",stdout);