/* * The author of this software is Eric Grosse. Copyright (c) 1993 by AT&T. * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ /* deprecated version of mirror.c, suitable for some non-POSIX systems */ #include "stdlib.h" #include "unistd.h" #include #include "string.h" #include #include "limits.h" #include #include #include "utime.h" #include "suffix.h" #ifndef LOOSE typedef unsigned long ulong; #endif #ifndef PATH_MAX #define PATH_MAX 1024 #endif #ifndef NAME_MAX #define NAME_MAX 32 #endif extern int Create(); extern int Error(); char *progname; static char **ftparg; static char ftpdir[PATH_MAX+1]; /* relative to starting directory here and on remote. No '/' on end. */ static int uncompressed; /* if 1, assume master site has no compression at all */ static int toftp; #define ftpcmd(cmd) printf("%s",cmd) #define MESS_SIZE "%s had size %lu, expected %lu\n" #define MESS_OWN "%s: not owner\n" #define MESS_BIG "string too big: %s" static int chtime(name, tim, len) char *name; ulong tim; ulong len; { struct stat s; time_t u[2]; if(stat(name,&s)!=0){ /* get actual time and length */ fprintf(stderr,"can't stat %s\n",name); return -1; } if((off_t)len!=s.st_size){ /* verify length is same */ fprintf(stderr,MESS_SIZE,name,(ulong)s.st_size,len); return -1; } u[0] = s.st_atime; u[1] = (time_t)tim; if(utime(name,u)!=0){ /* change mtime */ if(errno==EPERM){ fprintf(stderr,MESS_OWN,name); return -1; } fprintf(stderr,"can't utime %s\n",name); return -1; } return 0; } static walk(olddir, newdir) char *olddir; char *newdir; { char *so, *sn; char cdcmd[5+2*PATH_MAX]; /* see how far old and new agree */ for( so=olddir, sn=newdir; *so==*sn; so++, sn++){ if(*so=='/'){ olddir = so+1; newdir = sn+1; }else if(*so=='\0'){ olddir = so; newdir = sn; break; } } strcpy(cdcmd,"lcd "); while(so = strrchr(olddir,'/')){ /* walk up */ strcat(cdcmd,"../"); *so = '\0'; } if(olddir[0]!='\0') strcat(cdcmd,"../"); strcat(cdcmd,newdir); strcat(cdcmd,"\n"); if(strcmp(cdcmd,"lcd \n")!=0){ ftpcmd(cdcmd); /* local cd */ ftpcmd(cdcmd+1); /* remote cd */ } strcpy(olddir,newdir); } static int get(name, tim, len, sum, suffixlist) char *name; ulong tim; ulong len; ulong sum; Suffix *suffixlist; { char getcmd[5+NAME_MAX], work[PATH_MAX+1], *newdir, *basename, *suf; close(Create(name,0666)); /* make directories if necessary */ if(!toftp){ toftp = 1; printf("%s %s <<'!'\n",ftparg[0],ftparg[1]); ftparg += 2; ftpcmd("prompt\n"); ftpcmd("binary\n"); ftpcmd("verbose\n"); if(*ftparg){ /* starting directory on remote system */ if(strlen(*ftparg)+5>PATH_MAX) Error(MESS_BIG,*ftparg); sprintf(work,"cd %s\n",*ftparg++); ftpcmd(work); } } /* cut path into directory and basename */ if(strlen(name)+1>sizeof(work)) Error("filename overflow"); strcpy(work,name); if(basename = strrchr(work,'/')){ newdir = work; *basename++ = '\0'; }else{ newdir = ""; basename = work; } walk(ftpdir,newdir); /* cd as necessary */ strcmp(ftpdir,newdir)==0 || Error("dir mismatch: can't happen"); /* at last, get the file */ suf = ""; if(!uncompressed && need_compr(basename,suffixlist)) suf = ".Z"; /* might want to change this to ".z" for gzip someday */ sprintf(getcmd,"get %s%s\n",basename,suf); ftpcmd(getcmd); return 0; } int main(argc,argv) int argc; char **argv; { #define DIE Error("can't %s %s",cmd,name) ulong tim, len, sum; char cmd[21], name[2001]; Suffix *suffixlist; int err = 0; progname = argv[0]; if(argc!=5) Error("args: \n"); ftparg = &argv[1]; uncompressed = read_suffix(argv[4],&suffixlist); while(5==fscanf(stdin,"%20s %2000s %lu %lu %lx", cmd,name,&tim,&len,&sum)){ switch(*cmd){ case 'g': /* get */ get(name,tim,len,sum,suffixlist)==0 || DIE; break; case 'r': /* rm */ unlink(name)==0 || DIE; break; case 't': /* time */ chtime(name,tim,len); /* don't DIE, just keep going */ break; default: if(err++ < 10) fprintf(stderr,"? %s %s\n",cmd,name); } } if(toftp) printf("quit\n!\n"); if(err) exit(1); exit(0); }