📄 console_fe.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: console_fe.c,v 1.29.2.7 1999/08/19 22:09:27 joe Exp $*//* This is the console front end for sitecopy. * TODO: Some of the configuration stuff should be moved out of here. */#include <config.h>#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <stdio.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 <signal.h>#include <time.h>#include <getopt.h>#include <basename.h>#ifdef ENABLE_NLS#include <libintl.h>#define _(str) gettext(str)#else#define _(str) str#endif /* ENABLE_NLS */#include "frontend.h"#include "sites.h"#include "rcfile.h"#include "common.h"/* From lib/yesno.c */int yesno(void);/* The maximum number of sites which can be specified on the command * line */#define MAXSITES 20enum action_t { action_none, action_list, action_synch, action_fetch, action_update, action_catchup, action_init, action_view} action;const char *action_names[] = { NULL, _("Showing changes to"), _("Synchronizing"), _("Fetching"), _("Updating"), _("Catching up"), _("Initializing"), NULL};/* The short program name, basename(argv[0]) */const char *progname;const char *sitenames[MAXSITES]; /* the sites specified on the command line */int numsites; /* the number of sites specified */struct site_t *current_site; /* this is used to save the state if we * get signalled mid-update */bool needsite; /* Is a site name required for the given action? *//* User-specified options */bool allsites; /* Do they want all sites to be operated on? */bool listflat; /* Do they want the 'flat' list style */int quiet; /* How quiet do they want us to be? *//* Functions prototypes */void init( int, char ** );int main( int, char ** );void usage( void );void version( void );void site_normlist( struct site_t * );#if 0bool fe_ynprompt( void );#endifvoid abort_handler( int );void site_dumpsites( void );void init_sites( void );void abort_handler( int sig ) { /* Flush out debugging messages first */ fflush( stderr );#ifdef HAVE_STRSIGNAL printf( _("\n\n%s: Caught signal: %s (%d)\n"), progname, strsignal( sig ), sig );#else printf( _("\n\n%s: Caught signal %d\n"), progname, sig );#endif if( action == action_update && current_site!=NULL ) { printf( _("%s: In site update, saving current progress... "), progname ); fflush( stdout ); site_writefiles( current_site ); printf( _("done.\n") ); } printf( _("%s: Terminating.\n"), progname ); exit( 15 );}/* Produce the normal listing output for the given site. */void site_normlist( struct site_t *the_site ) { struct site_file_t *current; int count; if( the_site->numnew > 0 ) { printf( _("* These items have been added since the last update:\n") ); count = 0; for( current = the_site->files; current!=NULL; current=current->next) { if( current->diff == file_new ) { if( count++ ) printf( ", " ); if( current->dir ) printf( _("dir:") ); printf( "%s", current->rel_local); } } putchar( '\n' ); } if( the_site->numchanged > 0 ) { printf( _("* These items have been changed since the last update:\n")); count = 0; for( current = the_site->files; current!=NULL; current=current->next) { if( current->diff == file_changed ) { if( count++ ) printf( ", " ); printf( "%s", current->rel_local); } } putchar( '\n' ); } if( the_site->numdeleted > 0 ) { if( the_site->nodelete ) { printf( _("* These items have been deleted, but will be left on the server:\n") ); } else { printf( _("* These items have been deleted since the last update:\n")); } count = 0; for (current = the_site->files; current!=NULL; current=current->next) { if( current->diff == file_deleted ) { if( count++ ) printf( ", " ); if( current->dir ) printf( _("dir:") ); printf( "%s", current->rel_local ); } } putchar( '\n' ); } if( the_site->nummoved > 0 ) { printf( _("* These items have been moved since the last update:\n") ); count = 0; for (current = the_site->files; current!=NULL; current=current->next) { if( current->diff == file_moved ) { if( count++ ) printf( ", " ); printf( "%s->/%s", current->old->rel_local, current->directory ); } } putchar( '\n' ); }}void site_dumpsites( ) { struct site_t *current; for( current=all_sites; current!=NULL; current=current->next ) { /* FIXME: Possibly, make sure we have the actual port number first * so we don't have to mess around printing out the port */ printf( _("Site: %s\n\tServer: %s"), current->name, current->server ); printf( _(" Port: ") ); if( current->port == 0 ) { printf( _("%s\n"), current->driver->service_name ); } else { printf( _("%d\n"), current->port ); } printf( _("\tProtocol: %s Username: %s\n"), current->driver->protocol_name, current->username ); if( ! current->ftp_pasv_mode ) printf( _("\tPassive mode FTP will not be used.\n") ); printf( _("\tRemote directory: %s\n\tLocal directory: %s\n"), current->remote_root_user, current->local_root_user ); printf( _("\tPermissions: %s Symlinks: %s\n"), PERMSMODE( current ), SYMLINKSMODE( current ) ); if( current->nodelete ) printf( _("\tRemote files will not be deleted.\n") ); if( current->checkmoved ) printf( _("\tFiles will be moved remotely if moved locally.\n") ); }}void init( int argc, char *argv[] ) { int optc, opt_index; bool firstlist = false; extern char *optarg; extern int optind;#ifdef DEBUGGING char *shortopts = "d:acifhklp:qr:suvVy";#else char *shortopts = "acifhklp:qr:suvVy";#endif const struct option longopts[] = { /* Operation modes */ { "update", no_argument, NULL, 'u' }, { "initialize", no_argument, NULL, 'i' }, { "fetch", no_argument, NULL, 'f' }, { "synchronize", no_argument, NULL, 's' }, { "list", no_argument, NULL, 'l' }, { "flatlist", no_argument, &listflat, true }, { "keep-going", no_argument, NULL, 'k' }, { "help", no_argument, NULL, 'h' }, { "catchup", no_argument, NULL, 'c' }, { "view", no_argument, NULL, 'v' }, /* Options */ { "quiet", no_argument, &quiet, 1 }, { "silent", no_argument, &quiet, 2 }, { "rcfile", required_argument, NULL, 'r' }, { "storepath", required_argument, NULL, 'p' },#ifdef DEBUGGING { "debug", required_argument, NULL, 'd' },#endif { "prompting", no_argument, &fe_prompting, true }, { "allsites", no_argument, &allsites, true }, { "version", no_argument, NULL, 'V' }, { 0, 0, 0, 0 } }; #ifdef DEBUGGING /* We need these for setting up the debugging mask from * the command line */ extern int debug_mask; debug_mask = 0;#endif /* SETACTION is used to ensure only one opmode is specified * on the command line at a time. */#define SETACTION( newaction ) \ if( action != action_none ) { \ printf( _("%s: Error: Only specify ONE operation mode at a time.\n"), \ progname ); \ printf( _("Try `%s --help' for more information.\n"), progname ); \ exit( -1 ); \ } else { \ action = newaction; \ } /* Defaults */ allsites = fe_prompting = false; action = action_none; fe_prompting = false; progname = base_name( argv[0] ); needsite = false; /* Read the cmdline args */ while( (optc = getopt_long( argc, argv, shortopts, longopts, &opt_index)) != -1) { switch( optc ) { case 0: /* Make the action list mode if they gave --flatlist */ if( listflat == true ) action = action_list; break; case 'l': if( firstlist == false ) { SETACTION( action_list ); firstlist = true; } else { listflat = true; } break; case 's': SETACTION( action_synch ); break; case 'f': SETACTION( action_fetch ); break; case 'i': SETACTION( action_init ); break; case 'c': SETACTION( action_catchup ); break; case 'u': SETACTION( action_update ); break; case 'v': SETACTION( action_view ); allsites = true; /* so they get checked */ break; case 'q': quiet++; break; case 'r': if( strlen(optarg) != 0 ) { rcfile = strdup( optarg ); } else { usage( ); exit(-1); } break; case 'p': if( strlen(optarg) != 0 ) { if( optarg[strlen(optarg)] != '/' ) { copypath = malloc( strlen(optarg) + 2 ); strcpy( copypath, optarg ); strcat( copypath, "/" ); } else { copypath = strdup( optarg ); } } else { usage( ); exit(-1); } break;#ifdef DEBUGGING case 'd': /* set debugging level */ debug_mask = atoi(optarg); break;#endif case 'y': fe_prompting = true; break; case 'k': site_keepgoing = true; break; case 'a': allsites = true; break; case 'V': version( ); exit(-1); case 'h': usage( ); exit(-1); case '?': default: printf( _("Try `%s --help' for more information.\n"), progname ); exit(-1); } } /* Set the default action mode */ if( action == action_none ) action = action_list; /* Determine whether the specified action needs a site name * to operate on */ needsite = ((action==action_list) || (action==action_update) || \ (action==action_catchup) || (action==action_synch) || \ (action==action_fetch) || (action==action_init)); /* Get those site names off the end of the cmdline */ for( numsites = 0 ; optind < argc; optind++ ) { sitenames[numsites++] = argv[optind]; if( numsites == MAXSITES ) { printf( _("%s: Warning: Only %d sites can be specified on the command line!\nExtra entries are being skipped.\n"), progname, MAXSITES ); break; } }}#if 0/* Prompts for confirmation - returns */bool fe_ynprompt( ) { char in[BUFSIZ]; fgets( in, BUFSIZ, stdin ); return (*in == 'y'); /* only return true if they put a 'y' first */}#endifbool fe_can_update( const struct site_file_t *file ) { if( file->dir ) { if( file->diff == file_new ) { printf( _("Create %s/"), file->rel_local ); } else { printf( _("Delete %s/"), file->rel_local ); } } else { switch( file->diff ) { case file_changed: case file_new: printf( _("Upload %s"), file->rel_local ); break; case file_deleted: printf( _("Delete %s"), file->rel_local ); break; case file_moved: printf( _("Move %s->/%s"), file->old->rel_local, file->directory ); break; default: printf( "You've really broken it now.\n" ); break; } } printf( _("? (y/n) ") ); return yesno( );}/* Called when the given files is about to be updated */void fe_updating( const struct site_file_t *file ) { switch( quiet ) { case 0: if( file->dir ) { if( file->diff == file_new ) { printf( _("Creating %s/: "), file->rel_local+1 ); } else { printf( _("Deleting %s/: "), file->rel_local+1 ); } } else { switch( file->diff ) { case file_changed: case file_new: printf( _("Uploading %s: ["), file->rel_local+1 ); break; case file_deleted: printf( _("Deleting %s: "), file->rel_local+1 ); break; case file_moved: printf( _("Moving %s->%s: "), file->old->rel_local+1, file->directory ); break; default: printf( "You've really broken it now.\n" ); break; } } fflush( stdout ); break; case 1: printf( "%s\n", file->rel_local+1 ); break; default: break; }}void fe_updated( const struct site_file_t *file, const bool success, const char *error ) { if( quiet > 0 ) { if( ! success ) { printf( _("Failed to update %s:\n%s\n"), file->rel_local, error ); } return; } if( file->dir || (file->diff!=file_changed && file->diff!=file_new) ) { if( success ) { printf( _("done.\n") ); } else { printf( _("failed:\n%s\n"), error ); } } else { if( success ) { printf( _("] done.\n") );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -