📄 rcfile.c
字号:
/* sitecopy, for managing remote web sites. Copyright (C) 1998-99, Joe Orton <joe@orton.demon.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: rcfile.c,v 1.11.2.7 1999/08/19 21:43:26 joe Exp $*/#include <config.h>#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <errno.h>#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif #ifdef HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#include "common.h"#include "netrc.h"#include "rcfile.h"#include "socket.h"#include "sites.h"/** Global variables **/char *copypath;char *rcfile;char *netrcfile;char *home;bool havenetrc;/* These are used for reporting errors back to the calling procedures. */int rcfile_linenum; char *rcfile_err;/** Not quite so global variables **//* These are appeneded to $HOME */#define RCNAME "/." PACKAGE "rc"#define COPYNAME "/." PACKAGE "/"#define NETRCNAME "/.netrc"/* Stores the list of entries in the ~/.netrc */netrc_entry *netrc_list;const char *rc_get_netrc_password( const char *server, const char *username );/* rcfile_read will read the rcfile and fill given sites list. * This returns 0 on success, RC_OPENFILE if the rcfile could not * be read, or RC_CORRUPT if the rcfile was corrupt. * If it is corrupt, rcfile_linenum and rcfile_line are set to the * the corrupt line. */int rcfile_read( struct site_t **sites ) { FILE *fp; int state, last_state=8, ret=0; bool alpha, hash; char buf[BUFSIZ]; char *ch; char *ptr, key[BUFSIZ], val[BUFSIZ], val2[BUFSIZ]; /* Holders for the site info */ struct site_t *this_site, *last_site; if( (fp = fopen( rcfile, "r" )) == NULL ) { rcfile_err = strerror( errno ); return RC_OPENFILE; } last_site = this_site = NULL; rcfile_linenum = 0; rcfile_err = NULL; while( fgets( buf, sizeof(buf), fp ) != NULL ) { rcfile_linenum++; /* Put the line without the LF into the error buffer */ if( rcfile_err != NULL ) free( rcfile_err ); rcfile_err = strdup( buf ); ptr = strchr( rcfile_err, '\n' ); if( ptr != NULL ) *ptr = '\0'; state = 0; ptr = key; memset( key, 0, BUFSIZ ); memset( val, 0, BUFSIZ ); memset( val2, 0, BUFSIZ ); for( ch=buf; *ch!='\0'; ch++ ) { alpha = !isspace((unsigned)*ch); /* well, alphaish */ hash = (*ch == '#'); switch( state ) { case 0: /* whitespace at beginning of line */ if(hash) { state = 8; } else if(alpha) { *(ptr++) = *ch; state = 1; } break; case 1: /* key */ if(hash) { state = 8; } else if(!alpha) { ptr = val; state = 2; } else { *(ptr++) = *ch; } break; case 2: /* whitespace after key */ if(hash) { state = 8; } else if( *ch == '"' ) { state = 4; /* begin quoted value */ } else if ( alpha ) { *(ptr++) = *ch; state = 3; } break; case 3: /* unquoted value 1 */ if(hash) { state = 8; } else if( !alpha ) { ptr = val2; state = 5; } else { *(ptr++) = *ch; } break; case 4: /* quoted value 1 */ if( *ch == '"' ) { ptr = val2; state = 5; } else if( *ch == '\\' ) { last_state = 4; state = 9; } else { *(ptr++) = *ch; } break; case 5: /* whitespace after value 1 */ if(hash) { state = 8; } else if( *ch == '"' ) { state = 6; /* begin quoted value 2 */ } else if ( alpha ) { *(ptr++) = *ch; state = 7; /* begin unquoted value 2 */ } break; case 6: /* quoted value 2 */ if( *ch == '"' ) { state = 8; } else if( *ch == '\\' ) { last_state = 4; state = 9; } else { *(ptr++) = *ch; } break; case 7: /* unquoted value 2 */ if(hash) { state = 8; } else if( !alpha ) { state = 8; } else { *(ptr++) = *ch; } break; case 8: /* ignore till end of line */ break; case 9: /* a literal (\-slashed) in a value */ *(ptr++) = *ch; state = last_state; break; } } DEBUG( DEBUG_RCFILE, "Key [%s] Value: [%s] Value2: [%s]\n", key, val, val2); if( strlen( key ) == 0 ) { continue; } if( strlen( val ) == 0 ) { /* A key with no value. */ if( this_site == NULL ) { /* Need to be in a site! */ ret = RC_CORRUPT; break; } if( strcmp( key, "nodelete" ) == 0 ) { this_site->nodelete = true; } else if( strcmp( key, "checkmoved" ) == 0 ) { this_site->checkmoved = true; } else if( strcmp( key, "nooverwrite" ) == 0 ) { this_site->nooverwrite = true; } else { ret = RC_CORRUPT; break; } } else if( strlen( val2 ) == 0 ) { /* A key with a single value. */ if( strcmp( key, "site" ) == 0 ) { /* Beginning of a new Site */ last_site = this_site; /* Allocate new item */ this_site = malloc( sizeof( struct site_t ) ); /* Zero it out */ memset( this_site, 0, sizeof( struct site_t ) ); this_site->prev = last_site; if( last_site != NULL ) { /* next site */ last_site->next = this_site; } else { /* First site */ *sites = this_site; } this_site->name = strdup( val ); this_site->files = NULL; /* defaults... */ this_site->perms = sitep_ignore; this_site->symlinks = sitesym_follow; this_site->nodelete = false; this_site->checkmoved = false; this_site->driver = &ftp_driver; this_site->ftp_pasv_mode = true; /* Now work out the info filename */ this_site->infofile = malloc( strlen(copypath) + strlen(val) + 1); strcpy( this_site->infofile, copypath ); strcat( this_site->infofile, val ); } else if( this_site == NULL ) { ret = RC_CORRUPT; break; } else if( strcmp( key, "username" ) == 0 ) { /* username */ this_site->username = strdup( val ); } else if( strcmp( key, "server" ) == 0 ) { this_site->server = strdup( val ); } else if( strcmp( key, "port" ) == 0 ) { this_site->port = atoi( val ); } else if( strcmp( key, "proxy-server" ) == 0 ) { this_site->proxy_server = strdup( val ); } else if( strcmp( key, "proxy-port" ) == 0 ) { this_site->proxy_port = atoi( val ); } else if( strcmp( key, "proxy-password" ) == 0 ) { this_site->proxy_password = strdup( val ); } else if( strcmp( key, "proxy-username" ) == 0 ) { this_site->proxy_username = strdup( val ); } else if( strcmp( key, "password" ) == 0 ) { this_site->password = strdup( val ); } else if( strcmp( key, "url" ) == 0 ) { this_site->url = strdup( val ); } else if( strcmp( key, "remote" ) == 0 ) { /* Relative filenames must start with "~/" */ if( val[0] == '~' ) { if( val[1] == '/' ) { this_site->remote_isrel = true; } else { ret = RC_CORRUPT; break; } } else { /* Dirname doesn't begin with "~/" */ this_site->remote_isrel = false; } if( val[strlen(val)-1] != '/' ) strcat( val, "/" ); this_site->remote_root_user = strdup( val ); } else if( strcmp( key, "local" ) == 0 ) { /* Relative filenames must start with "~/" */ if( val[0] == '~' ) { if( val[1] == '/' ) { this_site->local_isrel = true; } else { ret = RC_CORRUPT; break; } } else { /* Dirname doesn't begin with a "~/" */ this_site->local_isrel = false; } if( val[strlen(val)-1] != '/' ) strcat( val, "/" ); this_site->local_root_user = strdup( val ); } else if( strcmp( key, "permissions") == 0 ) { if( strcmp( val, "ignore" ) == 0 ) { this_site->perms = sitep_ignore; } else if( strcmp( val, "exec" ) == 0 ) { this_site->perms = sitep_exec; } else if( strcmp( val, "all" ) == 0 ) { this_site->perms = sitep_all; } else { ret = RC_CORRUPT; break; } } else if( strcmp( key, "symlinks" ) == 0 ) { if( strcmp( val, "follow" ) == 0 ) { this_site->symlinks = sitesym_follow; } else if( strcmp( val, "maintain" ) == 0 ) { this_site->symlinks = sitesym_maintain; } else if( strcmp( val, "ignore" ) == 0 ) { this_site->symlinks = sitesym_ignore; } else { ret = RC_CORRUPT; break; } } else if( strcmp( key, "exclude" ) == 0 ) { struct exclude_t *newex; newex = malloc( sizeof( struct exclude_t ) ); newex->next = this_site->excludes; newex->prev = NULL; if( this_site->excludes != NULL ) this_site->excludes->prev = newex; this_site->excludes = newex; newex->pattern = strdup( val ); if( strchr( val, '/' ) != NULL ) { newex->haspath = true; } else { newex->haspath = false; } } else if( strcmp( key, "ascii") == 0 ) { /* Find the position in the array */ this_site->ascii[this_site->numascii] = strdup(val); this_site->numascii++; } else if( strcmp( key, "protocol" ) == 0 ) { if( strcmp( val, "ftp" ) == 0 ) { this_site->protocol = siteproto_ftp; this_site->driver = &ftp_driver; }#ifdef USE_DAV
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -