Back to index

avfs  1.0.1
utils.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998-2001  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU LGPL.
00006     See the file COPYING.LIB.
00007 */
00008 
00009 #include "utils.h"
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <unistd.h>
00013 
00014 #define VDEV_SEP_CHAR '#'
00015 
00016 struct fileinfo __av_dtable[AVFS_DTABLE_SIZE];
00017 char __av_cwd[PATHBUF_LEN];
00018 pthread_mutex_t __av_cwdlock;
00019 int __av_virtcwd;
00020 
00021 static int path_valid_virtual(const char *path)
00022 {
00023     const char *s = path;
00024 
00025     while(*s == '/')
00026         s++;
00027     
00028     for(; *s != '\0'; s++) {
00029         if(*s == '/')
00030             return 0;
00031         if(*s == ':')
00032             return 1;
00033     }
00034     
00035     return 0;
00036 }
00037 
00038 int __av_path_local(const char *path)
00039 {
00040     if(strchr(path, VDEV_SEP_CHAR) == NULL) {
00041         if(strchr(path, ':') == NULL)
00042             return 1;
00043         else if(path_valid_virtual(path))
00044             return 0;
00045         else
00046             return 1;
00047     }
00048     else
00049         return 0;
00050 }
00051 
00052 
00053 static int make_abs_path(const char *path, char *pathbuf)
00054 {
00055     unsigned int len;
00056 
00057     if(__av_cwd[0] == '\0') {
00058         if(getcwd(__av_cwd, PATHBUF_LEN) == NULL)
00059             return -errno;
00060     }
00061 
00062     len = strlen(__av_cwd) + 1 + strlen(path);
00063     if(len >= PATHBUF_LEN)
00064         return -ENAMETOOLONG;
00065 
00066     sprintf(pathbuf, "%s/%s", __av_cwd, path);
00067 
00068     return 0;
00069 }
00070 
00071 static int try_convert_path(const char *path, char *pathbuf)
00072 {
00073     const char *s;
00074     const char *prefixenv;
00075 
00076     if(strlen(path) + 32 > PATHBUF_LEN)
00077         return 0;
00078     
00079     for(s = path; *s != '\0'; s++) {
00080         if(*s == ':')
00081             break;
00082 
00083         if(!isalpha((int) *s) && !isdigit((int) *s) && *s != '-' && *s != '.')
00084             return 0;
00085     }
00086 
00087     if(s == path || *s == '\0' || (s[1] != '/' && s[1] != '\0'))
00088         return 0;
00089     
00090     prefixenv = getenv("AVFS_HOST_PREFIX");
00091     if(prefixenv == NULL)
00092         prefixenv = "rsh:";
00093 
00094     if(strlen(path) + strlen(prefixenv) + 32 > PATHBUF_LEN)
00095         return 0;
00096 
00097     sprintf(pathbuf, "/%c%s%.*s%s", VDEV_SEP_CHAR, prefixenv,
00098             s - path, path, s + 1);
00099     
00100     return 1;
00101 }
00102 
00103 int __av_get_abs_path(const char *path, char *pathbuf, const char **resp)
00104 {
00105     int res;
00106 
00107     if(path[0] == '/') {
00108         if(strchr(path, ':') != NULL) {
00109             const char *s;
00110 
00111             for(s = path; *s == '/'; s++);
00112             if(try_convert_path(s, pathbuf)) {
00113                 *resp = pathbuf;
00114                 return 0;
00115             }
00116         }
00117         *resp = path;
00118         return 0;
00119     }
00120 
00121     if(strchr(path, ':') != NULL) {
00122         if(try_convert_path(path, pathbuf)) {
00123             *resp = pathbuf;
00124             return 0;
00125         }
00126     }
00127 
00128     pthread_mutex_lock(&__av_cwdlock);
00129     res = make_abs_path(path, pathbuf);
00130     pthread_mutex_unlock(&__av_cwdlock);
00131     if(res == 0)
00132         *resp = pathbuf;
00133 
00134     return res;
00135 }
00136