iPXE
nfs_uri.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014 Marin Hannache <ipxe@mareo.fr>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  */
00019 
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <errno.h>
00023 #include <libgen.h>
00024 #include <ipxe/nfs_uri.h>
00025 
00026 /** @file
00027  *
00028  * Network File System protocol URI handling functions
00029  *
00030  */
00031 
00032 int nfs_uri_init ( struct nfs_uri *nfs_uri, const struct uri *uri ) {
00033         if ( ! ( nfs_uri->mountpoint = strdup ( uri->path ) ) )
00034                 return -ENOMEM;
00035 
00036         nfs_uri->filename = basename ( nfs_uri->mountpoint );
00037         if ( strchr ( uri->path, '/' ) != NULL )
00038                 nfs_uri->mountpoint = dirname ( nfs_uri->mountpoint );
00039 
00040         if ( nfs_uri->filename[0] == '\0' ) {
00041                 free ( nfs_uri->mountpoint );
00042                 return -EINVAL;
00043         }
00044 
00045         if ( ! ( nfs_uri->path = strdup ( nfs_uri->filename ) ) ) {
00046                 free ( nfs_uri->mountpoint );
00047                 return -ENOMEM;
00048         }
00049         nfs_uri->lookup_pos = nfs_uri->path;
00050 
00051         return 0;
00052 }
00053 
00054 char *nfs_uri_mountpoint ( const struct nfs_uri *uri ) {
00055         if ( uri->mountpoint + 1 == uri->filename ||
00056              uri->mountpoint     == uri->filename )
00057                 return "/";
00058 
00059         return uri->mountpoint;
00060 }
00061 
00062 int nfs_uri_next_mountpoint ( struct nfs_uri *uri ) {
00063         char *sep;
00064 
00065         if ( uri->mountpoint + 1 == uri->filename ||
00066              uri->mountpoint     == uri->filename )
00067                 return -ENOENT;
00068 
00069         sep = strrchr ( uri->mountpoint, '/' );
00070         uri->filename[-1] = '/';
00071         uri->filename     = sep + 1;
00072         *sep = '\0';
00073 
00074         free ( uri->path );
00075         if ( ! ( uri->path = strdup ( uri->filename ) ) ) {
00076                 uri->path = NULL;
00077                 return -ENOMEM;
00078         }
00079         uri->lookup_pos = uri->path;
00080 
00081         return 0;
00082 }
00083 
00084 int nfs_uri_symlink ( struct nfs_uri *uri, const char *symlink ) {
00085         size_t len;
00086         char *new_path;
00087 
00088         if ( ! uri->path )
00089                 return -EINVAL;
00090 
00091         if ( *symlink == '/' )
00092         {
00093                 if ( strncmp ( symlink, uri->mountpoint,
00094                                strlen ( uri->mountpoint ) ) != 0 )
00095                         return -EINVAL;
00096 
00097                 len = strlen ( uri->lookup_pos ) + strlen ( symlink ) - \
00098                       strlen ( uri->mountpoint );
00099                 if ( ! ( new_path = malloc ( len * sizeof ( char ) ) ) )
00100                         return -ENOMEM;
00101 
00102                 strcpy ( new_path, symlink + strlen ( uri->mountpoint ) );
00103                 strcpy ( new_path + strlen ( new_path ), uri->lookup_pos );
00104 
00105         } else {
00106                 len = strlen ( uri->lookup_pos ) + strlen ( symlink );
00107                 if ( ! ( new_path = malloc ( len * sizeof ( char ) ) ) )
00108                         return -ENOMEM;
00109 
00110 
00111                 strcpy ( new_path, symlink );
00112                 strcpy ( new_path + strlen ( new_path ), uri->lookup_pos );
00113         }
00114 
00115         free ( uri->path );
00116         uri->lookup_pos = uri->path = new_path;
00117 
00118         return 0;
00119 }
00120 
00121 char *nfs_uri_next_path_component ( struct nfs_uri *uri ) {
00122         char *sep;
00123         char *start;
00124 
00125         if ( ! uri->path )
00126                 return NULL;
00127 
00128         for ( sep = uri->lookup_pos ; *sep != '\0' && *sep != '/'; sep++ )
00129                 ;
00130 
00131         start = uri->lookup_pos;
00132         uri->lookup_pos = sep;
00133         if ( *sep != '\0' ) {
00134                 uri->lookup_pos++;
00135                 *sep = '\0';
00136                 if ( *start == '\0' )
00137                         return nfs_uri_next_path_component ( uri );
00138         }
00139 
00140         return start;
00141 }
00142 
00143 void nfs_uri_free ( struct nfs_uri *uri ) {
00144         free ( uri->mountpoint );
00145         free ( uri->path );
00146         uri->mountpoint = NULL;
00147         uri->path       = NULL;
00148 }