File Annotation
Not logged in
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Copyright (c) 2007 D. Richard Hipp
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is free software; you can redistribute it and/or
dbda8d6ce9 2007-07-21       drh: ** modify it under the terms of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License version 2 as published by the Free Software Foundation.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is distributed in the hope that it will be useful,
dbda8d6ce9 2007-07-21       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
dbda8d6ce9 2007-07-21       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
dbda8d6ce9 2007-07-21       drh: ** General Public License for more details.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** You should have received a copy of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License along with this library; if not, write to the
dbda8d6ce9 2007-07-21       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
dbda8d6ce9 2007-07-21       drh: ** Boston, MA  02111-1307, USA.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Author contact information:
dbda8d6ce9 2007-07-21       drh: **   drh@hwaci.com
dbda8d6ce9 2007-07-21       drh: **   http://www.hwaci.com/drh/
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: *******************************************************************************
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This file contains code for parsing URLs that appear on the command-line
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: #include "config.h"
dbda8d6ce9 2007-07-21       drh: #include "url.h"
dbda8d6ce9 2007-07-21       drh: 
3dcaed8d86 2007-07-28       dan: /* Parse a URI authority. The parsed syntax is:
3dcaed8d86 2007-07-28       dan: **
3dcaed8d86 2007-07-28       dan: **     [<username> : <password> @] <hostname> [: <port>]
3dcaed8d86 2007-07-28       dan: **
3dcaed8d86 2007-07-28       dan: ** TODO: If the input string does not match this pattern, results are
3dcaed8d86 2007-07-28       dan: ** undefined (but should not crash or anything nasty like that).
3dcaed8d86 2007-07-28       dan: */
3dcaed8d86 2007-07-28       dan: void url_parse_authority(char const *zUri, int *pIdx){
3dcaed8d86 2007-07-28       dan:   char *zUser = 0;
3dcaed8d86 2007-07-28       dan:   char *zPass = 0;
3dcaed8d86 2007-07-28       dan:   char *zHost = 0;
3dcaed8d86 2007-07-28       dan:   int iPort = 80;
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   int iFirst = *pIdx;
3dcaed8d86 2007-07-28       dan:   int iColon = -1;
3dcaed8d86 2007-07-28       dan:   int ii;
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   /* Scan for the magic "@". If the authority contains this character,
3dcaed8d86 2007-07-28       dan:   ** then we need to parse a username and password.
3dcaed8d86 2007-07-28       dan:   */
3dcaed8d86 2007-07-28       dan:   for(ii=iFirst; zUri[ii] && zUri[ii]!='@' && zUri[ii]!= '/'; ii++){
3dcaed8d86 2007-07-28       dan:     if( zUri[ii]==':' ) iColon = ii;
3dcaed8d86 2007-07-28       dan:   }
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   /* Parse the username and (optional) password. */
3dcaed8d86 2007-07-28       dan:   if( zUri[ii]=='@' ){
3dcaed8d86 2007-07-28       dan:     if( iColon>=0 ){
3dcaed8d86 2007-07-28       dan:       zUser = mprintf("%.*s", iColon-iFirst, &zUri[iFirst]);
3dcaed8d86 2007-07-28       dan:       zPass = mprintf("%.*s", ii-(iColon+1), &zUri[iColon+1]);
3dcaed8d86 2007-07-28       dan:     }else{
3dcaed8d86 2007-07-28       dan:       zUser = mprintf("%.*s", ii-iFirst, &zUri[iFirst]);
3dcaed8d86 2007-07-28       dan:     }
3dcaed8d86 2007-07-28       dan:     iFirst = ii+1;
3dcaed8d86 2007-07-28       dan:   }
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   /* Parse the hostname. */
3dcaed8d86 2007-07-28       dan:   for(ii=iFirst; zUri[ii] && zUri[ii]!=':' && zUri[ii]!= '/'; ii++);
3dcaed8d86 2007-07-28       dan:   zHost = mprintf("%.*s", ii-iFirst, &zUri[iFirst]);
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   /* Parse the port number, if one is specified. */
3dcaed8d86 2007-07-28       dan:   if( zUri[ii]==':' ){
3dcaed8d86 2007-07-28       dan:     iPort = atoi(&zUri[ii+1]);
3dcaed8d86 2007-07-28       dan:     for(ii=iFirst; zUri[ii] && zUri[ii]!= '/'; ii++);
3dcaed8d86 2007-07-28       dan:   }
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   /* Set the g.urlXXX variables to the parsed values. */
3dcaed8d86 2007-07-28       dan:   dehttpize(zUser);
3dcaed8d86 2007-07-28       dan:   dehttpize(zPass);
3dcaed8d86 2007-07-28       dan:   dehttpize(zHost);
3dcaed8d86 2007-07-28       dan:   g.urlUsername = zUser;
3dcaed8d86 2007-07-28       dan:   g.urlPassword = zPass;
3dcaed8d86 2007-07-28       dan:   g.urlName = zHost;
3dcaed8d86 2007-07-28       dan:   g.urlPort = iPort;
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:   *pIdx = ii;
3dcaed8d86 2007-07-28       dan: }
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan: /*
3dcaed8d86 2007-07-28       dan: ** Based on the values already stored in the other g.urlXXX variables,
3dcaed8d86 2007-07-28       dan: ** set the g.urlCanonical variable.
3dcaed8d86 2007-07-28       dan: */
3dcaed8d86 2007-07-28       dan: void url_set_canon(){
3dcaed8d86 2007-07-28       dan:   g.urlCanonical = mprintf("http://%T%s%T%s%T:%d%T",
3dcaed8d86 2007-07-28       dan:     (g.urlUsername ? g.urlUsername : ""),
3dcaed8d86 2007-07-28       dan:     (g.urlPassword ? ":" : ""),
3dcaed8d86 2007-07-28       dan:     (g.urlPassword ? g.urlPassword : ""),
3dcaed8d86 2007-07-28       dan:     (g.urlUsername ? "@" : ""),
3dcaed8d86 2007-07-28       dan:     g.urlName, g.urlPort, g.urlPath
3dcaed8d86 2007-07-28       dan:   );
3dcaed8d86 2007-07-28       dan:   /* printf("%s\n", g.urlCanonical); */
3dcaed8d86 2007-07-28       dan: }
3dcaed8d86 2007-07-28       dan: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Parse the given URL.  Populate variables in the global "g" structure.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: **      g.urlIsFile      True if this is a file URL
dbda8d6ce9 2007-07-21       drh: **      g.urlName        Hostname for HTTP:.  Filename for FILE:
dbda8d6ce9 2007-07-21       drh: **      g.urlPort        Port name for HTTP.
dbda8d6ce9 2007-07-21       drh: **      g.urlPath        Path name for HTTP.
dbda8d6ce9 2007-07-21       drh: **      g.urlCanonical   The URL in canonical form
dbda8d6ce9 2007-07-21       drh: **
3dcaed8d86 2007-07-28       dan: ** If g.uriIsFile is false, indicating an http URI, then the following
3dcaed8d86 2007-07-28       dan: ** variables are also populated:
3dcaed8d86 2007-07-28       dan: **
3dcaed8d86 2007-07-28       dan: **      g.urlUsername
3dcaed8d86 2007-07-28       dan: **      g.urlPassword
3dcaed8d86 2007-07-28       dan: **
3dcaed8d86 2007-07-28       dan: ** TODO: At present, the only way to specify a username is to pass it
3dcaed8d86 2007-07-28       dan: ** as part of the URI. In the future, if no password is specified,
3dcaed8d86 2007-07-28       dan: ** fossil should use the get_passphrase() routine (user.c) to obtain
3dcaed8d86 2007-07-28       dan: ** a password from the user.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void url_parse(const char *zUrl){
dbda8d6ce9 2007-07-21       drh:   int i, j, c;
dbda8d6ce9 2007-07-21       drh:   char *zFile;
dbda8d6ce9 2007-07-21       drh:   if( strncmp(zUrl, "http:", 5)==0 ){
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 0;
3dcaed8d86 2007-07-28       dan: 
3dcaed8d86 2007-07-28       dan:     i = 7;
3dcaed8d86 2007-07-28       dan:     url_parse_authority(zUrl, &i);
dbda8d6ce9 2007-07-21       drh:     g.urlPath = mprintf(&zUrl[i]);
dbda8d6ce9 2007-07-21       drh:     dehttpize(g.urlPath);
3dcaed8d86 2007-07-28       dan:     url_set_canon();
3dcaed8d86 2007-07-28       dan: 
dbda8d6ce9 2007-07-21       drh:   }else if( strncmp(zUrl, "file:", 5)==0 ){
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     if( zUrl[5]=='/' && zUrl[6]=='/' ){
dbda8d6ce9 2007-07-21       drh:       i = 7;
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       i = 5;
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s", &zUrl[i]);
dbda8d6ce9 2007-07-21       drh:   }else if( file_isfile(zUrl) ){
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s", zUrl);
dbda8d6ce9 2007-07-21       drh:   }else if( file_isdir(zUrl)==1 ){
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s/FOSSIL", zUrl);
dbda8d6ce9 2007-07-21       drh:     if( file_isfile(zFile) ){
dbda8d6ce9 2007-07-21       drh:       g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       free(zFile);
dbda8d6ce9 2007-07-21       drh:       fossil_panic("unknown repository: %s", zUrl);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }else{
dbda8d6ce9 2007-07-21       drh:     fossil_panic("unknown repository: %s", zUrl);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( g.urlIsFile ){
dbda8d6ce9 2007-07-21       drh:     Blob cfile;
dbda8d6ce9 2007-07-21       drh:     dehttpize(zFile);
dbda8d6ce9 2007-07-21       drh:     file_canonical_name(zFile, &cfile);
dbda8d6ce9 2007-07-21       drh:     free(zFile);
dbda8d6ce9 2007-07-21       drh:     g.urlName = mprintf("%b", &cfile);
dbda8d6ce9 2007-07-21       drh:     g.urlCanonical = mprintf("file://%T", g.urlName);
dbda8d6ce9 2007-07-21       drh:     blob_reset(&cfile);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh: }