TUM-Logo

libRASCH

 

Home
 

General

About libRASCH/News
Design
Screen shots
Sample programs (with source code)
License
 

Download

libRASCH
Tools
 

Documentation

User
Developer
 

Resources

Mailing list
Supported Formats
Plugins
Status
Links
 
Contact
About this site
 
Last updated
Tue Mar 27 23:03:52 2007
libRASCH: ra_file.c Source File

ra_file.c

Go to the documentation of this file.
00001 
00009 /*----------------------------------------------------------------------------
00010  *
00011  * Copyright (C) 2002-2004, Raphael Schneider
00012  * See the file COPYING for information on usage and redistribution.
00013  *
00014  * $Header: /home/cvs_repos.bak/librasch/src/shared/ra_file.c,v 1.20 2004/07/15 18:23:29 rasch Exp $
00015  *
00016  *--------------------------------------------------------------------------*/
00017 
00018 #include <string.h>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 
00022 #ifdef WIN32
00023 #include <windows.h>
00024 #endif
00025 
00026 #ifdef LINUX
00027 #include <dirent.h>
00028 #include <ctype.h>
00029 #include <unistd.h>
00030 #include <sys/stat.h>
00031 #include <errno.h>
00032 #endif
00033 
00034 #define _LIBRASCH_BUILD
00035 #include <ra.h>
00036 #include <ra_priv.h>
00037 #include <ra_file.h>
00038 #include <pl_general.h>
00039 
00040 /* private prototypes */
00041 int find_files_win32(const char *dir, const char *mask, char ***f, int *num, long *size);
00042 int find_files_linux(const char *dir, const char *mask, char ***f, int *num, long *size);
00043 FILE *_ra_fopen(const char *fn, const char *mode, int dir_based, char *fn_ok, int buf_len);
00044 
00045 
00055 int
00056 ra_get_filename(const char *fn, int dir_based, char *buf, int buf_len)
00057 {
00058         int ret = 0;
00059         FILE *fp;
00060         char *fn_ok;
00061 
00062         fn_ok = malloc(sizeof(char) * MAX_PATH_RA);
00063         fp = _ra_fopen(fn, "rb", dir_based, fn_ok, MAX_PATH_RA);
00064         if (fp)
00065         {
00066                 strncpy(buf, fn_ok, buf_len);
00067                 fclose(fp);
00068         }
00069         else
00070                 ret = -1;
00071 
00072         free(fn_ok);
00073 
00074         return ret;
00075 } /* ra_get_filename() */
00076 
00077 
00087 FILE *
00088 ra_fopen(const char *fn, const char *mode, int dir_based)
00089 {
00090         return _ra_fopen(fn, mode, dir_based, NULL, 0);
00091 } /* ra_fopen() */
00092 
00103 FILE *
00104 _ra_fopen(const char *fn, const char *mode, int dir_based, char *fn_ok, int buf_len)
00105 {
00106         FILE *fp = NULL;
00107         char *pos, *pos_save;
00108         int is_lower = -1;
00109         char *pos_sep = NULL;
00110         char fn_locale[MAX_PATH_RA];
00111 
00112         /* IIUIC toupper() and tolower() respect locale setting (at least on Linux),
00113            therfore do everything using the "locale"-string */
00114         utf8_to_local(fn, fn_locale, MAX_PATH_RA);
00115 
00116         /* i18n: do not care about the mode string (I think it will be always ASCII char's) */
00117 
00118         fp = fopen(fn_locale, mode);
00119         if (fp)
00120                 goto found;
00121 
00122         /* fopen failed, perhaps the notation (upper-/lower-case) of the filename is different */
00123         /* when NOT dir-based check if a reverse of the character case helps */
00124         if (!dir_based)
00125         {
00126                 pos = strrchr(fn_locale, SEPERATOR);
00127                 if (pos == NULL)
00128                         pos = fn_locale;
00129 
00130                 pos_save = pos;
00131                 while (*pos)
00132                 {
00133                         if (islower(*pos))
00134                                 *pos = toupper(*pos);
00135                         else
00136                                 *pos = tolower(*pos);
00137                         pos++;
00138                 }
00139                 fp = fopen(fn_locale, mode);
00140                 if (fp)
00141                         goto found;
00142 
00143                 /* not found, undo changes */
00144                 pos = pos_save;
00145                 while (*pos)
00146                 {
00147                         if (islower(*pos))
00148                                 *pos = toupper(*pos);
00149                         else
00150                                 *pos = tolower(*pos);
00151                         pos++;
00152                 }
00153         }
00154 
00155         /* fopen failed, perhaps the file-extension has some character case differences */
00156         pos = strrchr(fn_locale, '.');
00157 
00158         /* if measurement-files are in a directory, search for extension of directory */
00159         if (dir_based && pos)
00160         {
00161                 pos_sep = strrchr(fn_locale, SEPERATOR);
00162                 if (pos_sep && (pos > pos_sep))
00163                 {
00164                         *pos_sep = '\0';
00165                         pos = strrchr(fn_locale, '.');
00166                         *pos_sep = SEPERATOR;
00167                 }
00168         }
00169         
00170         if (pos == NULL)
00171                 return NULL;
00172 
00173         /* reverse character case (for dir-based meas. reverse char-case for file also) */
00174         pos++;                  /* '.' don't need to be handled */
00175         pos_save = pos;
00176         while (*pos)
00177         {
00178                 if (is_lower == -1)
00179                         is_lower = islower(*pos);
00180 
00181                 if (islower(*pos))
00182                         *pos = toupper(*pos);
00183                 else
00184                         *pos = tolower(*pos);
00185                 pos++;
00186         }
00187 
00188         /* and now try again to open file */
00189         fp = fopen(fn_locale, mode);
00190         if (!fp && dir_based && pos_sep)
00191         {
00192                 /* change char-case of extension back but leave the file-name reversed */
00193                 pos = pos_save;
00194                 while (*pos && (pos != pos_sep))
00195                 {
00196                         if (is_lower) /* was reversed before */
00197                                 *pos = tolower(*pos);
00198                         else
00199                                 *pos = toupper(*pos);
00200                         pos++;
00201                 }
00202                 fp = fopen(fn_locale, mode);
00203                 if (!fp)
00204                 {
00205                         /* if still not worked, try 4th possibility */
00206                         pos = pos_save;
00207                         while (*pos)
00208                         {
00209                                 if (islower(*pos))
00210                                         *pos = toupper(*pos);
00211                                 else
00212                                         *pos = tolower(*pos);
00213                                 pos++;
00214                         }
00215                         fp = fopen(fn_locale, mode);
00216                 }
00217         }
00218 
00219  found:
00220         if ((buf_len > 0) && (fn_ok != NULL) && fp)
00221                 strncpy(fn_ok, fn_locale, buf_len);
00222 
00223         return fp;
00224 } /* _ra_fopen() */
00225 
00226 
00238 int
00239 find_meas(const char *dir, const char *mask, struct find_meas *f, int (*check_meas) (const char *))
00240 {
00241         int n, i;
00242         char **files;
00243 
00244         n = 0;
00245         files = NULL;
00246 
00247         if (find_files(dir, mask, &files, &n, NULL) != 0)
00248                 return -1;
00249 
00250 #ifdef WIN32
00251         if (f->names == NULL)
00252                 f->names = GlobalAlloc(GMEM_FIXED, sizeof(char *) * (f->num + n));
00253         else
00254         {
00255                 char **t = GlobalAlloc(GMEM_FIXED, sizeof(char *) * (f->num + n));
00256                 memcpy(t, f->names, sizeof(char *) * f->num);
00257                 GlobalFree(f->names);
00258                 f->names = t;
00259         }
00260 #else
00261         f->names = realloc(f->names, sizeof(char *) * (f->num + n));
00262 #endif
00263         for (i = 0; i < n; i++)
00264         {
00265                 if ((*check_meas) (files[i]))
00266                 {
00267                         f->names[f->num] = ra_alloc_mem(sizeof(char) * strlen(files[i]) + 1);
00268                         strcpy(f->names[f->num], files[i]);
00269                         f->num++;
00270                 }
00271 
00272                 free(files[i]);
00273         }
00274         free(files);
00275 
00276         return 0;
00277 } /* find_meas() */
00278 
00279 
00291 int
00292 find_files(const char *dir, const char *mask, char ***f, int *num, long *size)
00293 {
00294         int ret = -1;
00295         long s = 0;
00296 
00297 #ifdef WIN32
00298         ret = find_files_win32(dir, mask, f, num, &s);
00299 #endif
00300 
00301 #ifdef LINUX
00302         ret = find_files_linux(dir, mask, f, num, &s);
00303 #endif
00304 
00305         if (size)
00306                 *size = s;
00307 
00308         return ret;
00309 } /* find_files() */
00310 
00311 
00322 #ifdef WIN32
00323 int
00324 find_files_win32(const char *dir, const char *mask, char ***f, int *num, long *size)
00325 {
00326         char fm[MAX_PATH_RA];
00327         WIN32_FIND_DATA find;
00328         HANDLE h;
00329         char dir_locale[MAX_PATH_RA];
00330 
00331         if (dir == NULL)
00332                 sprintf(fm, "%s", mask);
00333         else
00334         {
00335                 sprintf(fm, "%s\\%s", dir, mask);
00336                 /* will be needed later */
00337                 utf8_to_local(dir, dir_locale, MAX_PATH_RA);
00338         }
00339         utf8_to_local_inplace(fm, MAX_PATH_RA);
00340 
00341         h = FindFirstFile(fm, &find);
00342         if (h == INVALID_HANDLE_VALUE)
00343                 return -1;
00344 
00345         *size = 0;
00346         do
00347         {
00348                 char t[MAX_PATH_RA];
00349 
00350                 if ((strcmp(find.cFileName, ".") == 0) || (strcmp(find.cFileName, "..") == 0))
00351                         continue;
00352 
00353                 (*num)++;
00354                 *f = realloc(*f, sizeof(char *) * *num);
00355                 if (dir)
00356                         sprintf(t, "%s%c%s", dir_locale, SEPERATOR, find.cFileName);
00357                 else
00358                         sprintf(t, "%s", find.cFileName);
00359 
00360                 local_to_utf8_inplace(t, MAX_PATH_RA);
00361 
00362                 (*f)[*num - 1] = malloc(strlen(t) + 1);
00363                 strcpy((*f)[*num - 1], t);
00364 
00365                 *size += find.nFileSizeLow;     /* TODO: think about how to handle .nFileSizeHigh */
00366         }
00367         while (FindNextFile(h, &find));
00368         FindClose(h);
00369 
00370         return 0;
00371 }                               /* find_files_win32() */
00372 
00373 #endif /* WIN32 */
00374 
00385 #ifdef LINUX
00386 int
00387 find_files_linux(const char *dir, const char *mask, char ***f, int *num, long *size)
00388 {
00389         char dir_locale[MAX_PATH_RA];
00390         DIR *d;
00391         struct dirent *de;
00392         struct stat s;
00393         int mlen, mlen_use;
00394         char mask_use[MAX_PATH_RA];
00395 
00396         /* handle wildchar's (i.e. delete them here but chek for them later, see below)  */
00397         mlen = strlen(mask);
00398         if (mlen > 0)
00399         {
00400                 memset(mask_use, 0, MAX_PATH_RA);
00401                 if (mask[0] == '*')
00402                         strcpy(mask_use, mask+1);
00403                 else if (mask[mlen-1] == '*')
00404                         strncpy(mask_use, mask, mlen-1);
00405         }
00406         utf8_to_local_inplace(mask_use, MAX_PATH_RA);
00407         mlen_use = strlen(mask_use);
00408 
00409         memset(dir_locale, 0, MAX_PATH_RA);
00410         utf8_to_local(dir, dir_locale, MAX_PATH_RA);
00411 
00412         d = opendir(dir_locale);
00413         if (d == NULL)
00414                 return 0;       /* TODO: think if an error (dir not exist) should be set */
00415 
00416         while ((de = readdir(d)))
00417         {
00418                 char t[MAX_PATH_RA];
00419                 char name_utf8[MAX_PATH_RA];
00420                 int len = strlen(de->d_name);
00421 
00422                 /* skip current and parent directory */
00423                 if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0))
00424                         continue;
00425 
00426                 /* if no mask or mask == '*' -> get all files in directory; if not check
00427                    if name match with mask */
00428                 if ((mlen > 0) && !((mask[0] == '*') && (mlen == 1)))
00429                 {
00430                         /* if the current filename is shorter than mask, try the next one */
00431                         if (len < (mlen-1))
00432                                 continue;
00433 
00434                         /* up to now only handle '*' as wildcard character (and only at the beginning
00435                            or at the end of the mask) */
00436                         memset(t, 0, MAX_PATH_RA);
00437                         if (mask[0] == '*')
00438                                 strcpy(t, &(de->d_name[len-(mlen-1)]));
00439                         else if (mask[mlen-1] == '*')
00440                                 strncpy(t, de->d_name, mlen-1);
00441                         /* use case-insensitive compare to allow extensions with different case */
00442                         if (RA_STRICMP(t, mask_use) != 0)
00443                                 continue;
00444                 }
00445 
00446                 (*num)++;
00447                 *f = realloc(*f, sizeof(char *) * (*num));
00448 
00449                 local_to_utf8(de->d_name, name_utf8, MAX_PATH_RA);
00450                 sprintf(t, "%s%c%s", dir, SEPERATOR, name_utf8);
00451 
00452                 (*f)[(*num)-1] = malloc(strlen(t) + 1);
00453                 strcpy((*f)[(*num)-1], t);
00454                 stat(t, &s);
00455                 *size += s.st_size;
00456         }
00457         closedir(d);
00458 
00459         return 0;
00460 } /* find_files_linux() */
00461 
00462 
00463 #endif /* LINUX */
00464 
00465 
00472 int
00473 make_dir(const char *dir)
00474 {
00475         int ret = 0;
00476         char dir_locale[MAX_PATH_RA];
00477 
00478         utf8_to_local(dir, dir_locale, MAX_PATH_RA);
00479         
00480 #ifdef WIN32
00481         if (CreateDirectory(dir_locale, NULL) == FALSE)
00482                 ret = -1;
00483 #endif /* WIN32 */
00484 
00485 #ifdef LINUX
00486         ret = mkdir(dir_locale, ~0);
00487         if (ret != 0)
00488                 ret = errno;
00489 #endif /* LINUX */
00490 
00491         return ret;
00492 } /* make_dir() */
00493 
00494 
00503 int
00504 copy_move_file(const char *file, const char *dest_dir, int copy)
00505 {
00506         int ret = 0;
00507         char new_file[MAX_PATH_RA];
00508         char *p;
00509         char file_locale[MAX_PATH_RA];
00510         char new_file_locale[MAX_PATH_RA];
00511         
00512         p = strrchr(file, SEPERATOR);
00513         if (p == NULL)
00514                 sprintf(new_file, "%s%c%s", dest_dir, SEPERATOR, file);
00515         else
00516                 sprintf(new_file, "%s%c%s", dest_dir, SEPERATOR, p+1);
00517 
00518         utf8_to_local(file, file_locale, MAX_PATH_RA);
00519         utf8_to_local(new_file, new_file_locale, MAX_PATH_RA);
00520 
00521 #ifdef WIN32
00522         if (copy)
00523         {
00524                 /* overwrite file if new_file exists */
00525                 if (CopyFile(file_locale, new_file_locale, 0) == FALSE)
00526                         ret = -1;
00527         }
00528         else
00529         {
00530                 if (MoveFileEx(file_locale, new_file_locale, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) == FALSE)
00531                         ret = -1;
00532         }
00533 #endif /* WIN32 */
00534 
00535 #ifdef LINUX
00536         if (copy)
00537         {
00538                 /* it seems that it exist no copy function in libc */
00539                 FILE *fp_in, *fp_out;
00540                 unsigned char buf[1024];
00541                 size_t len;
00542 
00543                 fp_in = fopen(file_locale, "rb");
00544                 fp_out = fopen(new_file_locale, "wb");
00545                 if (!fp_in || !fp_out)
00546                         return -1;
00547 
00548                 while ((len = fread(buf, 1, 1024, fp_in)))
00549                         fwrite(buf, 1, len, fp_out);
00550                 fclose(fp_in);
00551                 fclose(fp_out);
00552         }
00553         else
00554                 ret = rename(file_locale, new_file_locale);
00555 
00556         if (ret != 0)
00557                 ret = errno;
00558 #endif /* LINUX */
00559 
00560         return ret;
00561 } /* copy_move_file() */
00562 
00563 
00570 int
00571 delete_file(const char *file)
00572 {
00573         int ret = 0;
00574         char file_locale[MAX_PATH_RA];
00575 
00576 #ifdef WIN32
00577         DWORD attrib;
00578 #endif
00579 #ifdef LINUX
00580         struct stat s;
00581 #endif
00582 
00583         utf8_to_local(file, file_locale, MAX_PATH_RA);
00584 
00585 #ifdef WIN32
00586         attrib = GetFileAttributes(file);
00587         if (attrib & FILE_ATTRIBUTE_DIRECTORY)
00588         {
00589                 if (RemoveDirectory(file_locale) == FALSE)
00590                         ret = -1;
00591         }
00592         else
00593         {
00594                 if (DeleteFile(file_locale) == FALSE)
00595                         ret = -1;
00596         }
00597 #endif /* WIN32 */
00598 
00599 #ifdef LINUX
00600         stat(file_locale, &s);
00601         if (S_ISDIR(s.st_mode))
00602                 ret = rmdir(file_locale);
00603         else
00604                 ret = unlink(file_locale);
00605 
00606         if (ret != 0)
00607                 ret = errno;
00608 #endif /* LINUX */
00609 
00610         return ret;
00611 } /* delete_file() */

Generated on Fri May 27 11:32:39 2005 for libRASCH by  doxygen 1.4.2