diff options
Diffstat (limited to 'lib/libftp/utils/uftp.c')
-rw-r--r-- | lib/libftp/utils/uftp.c | 824 |
1 files changed, 824 insertions, 0 deletions
diff --git a/lib/libftp/utils/uftp.c b/lib/libftp/utils/uftp.c new file mode 100644 index 0000000..4c8961f --- /dev/null +++ b/lib/libftp/utils/uftp.c @@ -0,0 +1,824 @@ +/* File Transfer Protocol Toolkit based on libftp */ + +#include "uftp.h" +#include <varargs.h> + + +FTP *ftp[NFRAMES]; +LINKINFO iftp[NFRAMES]; +int frame=0; + + +int status; +jmp_buf start; +int lastcmd=0; +int glassmode=0; +int trymode=1; +int restmode=1; +int hashmode=0; +int sleeptime=30; +time_t noopinterval=0; +time_t nooptimeout=1; +time_t prevtime=0; + +String cmd; +String prompt="%T %u@%H:%d> "; +String defaultuser; + +ALIAS *firstalias=NULL; + +/* if main have any arguments, interprets each it as command with args */ + + +main(int argc, char **argv) + +{ + register int i; + register char *p1; + FILE *fp; + String tmp; + + if (setjmp(start)!=0) + goto main_loop; + + setsignals(); + + + + FtpSetErrorHandler(&FtpInit,my_error); + FtpSetIOHandler(&FtpInit,my_error); + + strcpy(defaultuser,getpwuid(getuid())->pw_name); + + + memset(ftp,0,sizeof(FTP*)*NFRAMES); + memset(iftp,0,sizeof(LINKINFO)*NFRAMES); + + + + batch(SYSTEMRC); + + if (access(getrcname(),F_OK)) + { + FILE *out=fdopen(open(getrcname(),O_WRONLY|O_CREAT|O_TRUNC,0700),"w"); + + printf("Create default rc-file \"%s\"\n",getrcname()); + + if (out==NULL) + perror(getrcname()); + + else + { + + fprintf(out,"set timeout 120\nset hash\nset debug\nset bin\n"); + fprintf(out,"set prompt \"%%T %%u@%%h:%%d\\> \"\n"); + fprintf(out,"alias a alias\na ed ! emacs\nalias tn ! telnet\n"); + + fclose(out); + } + } + + + batch(getrcname()); + batch(getaliasrcname()); + + + for (i=1, tmp[0]=0; i< argc; i++) + { + strcat(tmp,argv[i]); + if (i+1!=argc) strcat(tmp," "); + } + + if (tmp[0]!=0) + { + String new; + +/* + if (!strcmp(defaultuser,"ftp") || !strcmp(defaultuser,"anonymous")) + strcpy(new,"ftp "); + else +*/ + strcpy(new,"open "); + + if (ifalias(tmp)) + execute (tmp); + else + strcat(new,tmp), + execute(new); + } + + +main_loop: + + setsignals(); + + while (1) + { + + setjmp(start); + if (lastcmd) exit(0); + + + if (isatty(fileno(stdin))) + p1=readline(getprompt()); + else + p1=gets(cmd); + + if (p1==NULL) + { + putchar('\n'); + exit(0); + } + + strcpy(cmd,p1); + + if (cmd[0]) add_history(cmd); + execute(cmd); + } +} + +INLINE char *findspace(char *str) +{ + while ( !isspace(*str) && *str != '\0' ) str++; + return str; +} + + + +char *word(char *str, int n) +{ + String new; + register char *p1, *p2; + register int i; + + strcpy(new,str); + + p1=new; + + while (isspace(*p1)) p1++; + + if (n>1 ) + for (i=0;i<n-1;i++) /* Skip n-1 words */ + { + if ((*p1=='"')||(*p1=='\'')) + { + p1=strchr(p1+1,*p1); + if (p1==NULL) return ""; + p1++; + while ( isspace(*p1) ) p1++; + continue; + } + p1=findspace(p1); + if ( *p1=='\0' ) return ""; + p1++; + while ( isspace(*p1) ) p1++; + } + + if ((*p1=='"')|(*p1=='\'')) + { + p2=strchr(p1+1,*p1); + if (p2==NULL) return p1+1; + *p2=0; + return p1+1; + } + + if ((p2=findspace(p1)) != NULL ) + { + *p2=0; + return p1; + } + return ""; +} + + +/* Exacute few command separated by ';' . The character ' must use for mark complex + works*/ + +execute (char *cmd) +{ + String w1,w2,w3,w4,w5,w6; + String newcmd; + char *p; + + if (!*cmd || *cmd=='#' ) return; + + for ( p=newcmd ; *cmd; cmd++) + { + if ( *cmd == '\'' ) + { + *p++=*cmd++; + while ( *cmd != '\'' && *cmd != 0 ) *p++=*cmd++; + if ( *cmd == 0 ) + return puts("Unbalanced \', please corrected!\n"); + *p++=*cmd; + continue; + } + + if ( *cmd == ';' ) + { + *p=0; + execute(newcmd); + p=newcmd; + continue; + } + *p++=*cmd; + } + + + *p=0; + cmd=newcmd; + + if ( *cmd=='\\' ) + cmd++; + else + { + String new; + strcpy(new,"\\"); + strcat(new,expandalias(cmd)); + return execute(new); + } + + if ( *cmd == '!' ) + { + int pid,_pid; + int status; + + if (!(pid=fork())) + { + execlp((getenv("SHELL")==NULL)?"/bin/sh":(char *)getenv("SHELL"), + "shell","-c",cmd+1,NULL); + } + + while(1) + { + _pid=wait(&status); + if (_pid==pid) + return; + } + } + + + redir(cmd); + + if (cmd[strlen(cmd)-1]=='&') + { + String tmp; + + cmd[strlen(cmd)-1]=0; + + strcpy(tmp,"bg "); + strcat(tmp,cmd); + + strcpy(cmd,tmp); + } + + strcpy(w1,word(cmd,1)); + strcpy(w2,word(cmd,2)); + strcpy(w3,word(cmd,3)); + strcpy(w4,word(cmd,4)); + strcpy(w5,word(cmd,5)); + strcpy(w6,word(cmd,6)); + + return executev(w1,w2,w3,w4,w5,w6); +} + +executev(ARGS) +{ + CMDS *xcmd=&cmds[0]; + String tmp; + + if (isdigit(*w1)) + return + atoi(w1)<NFRAMES?frame=atoi(w1):0, + executev(w2,w3,w4,w5,w6,""); + + while ( xcmd -> cmd != NULL ) + { + if ( !strcmp(xcmd->cmd,w1) && (xcmd -> func != NULL) ) + { + int status; + + if ( xcmd -> need && LINK == NULL) + return puts("Need connection to server"); + iftp[frame].lock=1; unsetsignals(); + status = (*xcmd->func)(w1,w2,w3,w4,w5,w6); + iftp[frame].lock=0; setsignals(); + redirback(); + return status; + } + xcmd++; + } + + + if (LINK!=NULL && glassmode) + return FtpCommand(LINK,cmd,"",0,EOF); + + printf("%s: unknown command\n",w1); + fflush(stdout); + return -1; +} + + +void intr(int sig) +{ + printf("Interupted by signal %d\n",sig); + if (LINK!=NULL) FtpSetHashHandler(LINK,NULL); + setsignals(); + reset_termio(); /* From readline */ + prevtime = time((time_t *)0); + longjmp(start,1); +} + +newframe(int connecteble) +{ + register int i; + + if (connecteble) + for (i=0; i<NFRAMES; i++) if (ftp[i]!=NULL) return frame=i; + for (i=0; i<NFRAMES; i++) if (ftp[i]==NULL) return frame=i; + return -1; +} + +STATUS my_error(FTP *ftp, int code, char *msg) +{ + + if (code==LQUIT||(ftp==NULL)) log(msg); + else + FtpLog(ftp->title,msg); + + if ( abs(code) == 530 && (strstr(msg,"anonymous")!=NULL)) + { + Ftp_reopen(); + longjmp(start,1); + } + longjmp(start,1); +} + +char *getrcname() +{ + static String rcpath; + struct passwd *pwd=getpwuid(getuid()); + + sprintf(rcpath,"%s/.uftprc",pwd->pw_dir); + return rcpath; +} + +char *getaliasrcname() +{ + static String rcpath; + struct passwd *pwd=getpwuid(getuid()); + + sprintf(rcpath,"%s/.uftp_aliases",pwd->pw_dir); + return rcpath; +} + +char *makestr(va_alist) + va_dcl +{ + char *p1; + va_list args; + String new={0}; + + va_start(args); + + while(1) + { + p1=va_arg(args,char *); + if (p1==NULL) break; + if (*p1!=0) + { + if (new[0]!=0) strcat(new," "); + strcat(new,p1); + } + } + va_end(args); + return new; +} + + +#define ADD(str,chr) (*str++=chr,*str=0) + +INLINE ADDSTR(char **str, char *str1) +{ + while (*str1) *(*str)++=*str1++; +} + +char *expandalias(char *str) +{ + ALIAS *a=firstalias; + String new={0},w1={0}; + char *p,*p1=new,*args; + int dollar=0; + + strcpy(w1,word(str,1)); + + if ( (p=strchr(str,' '))!=NULL ) + args=p+1; + else + args=""; + + while (a) + { + if (!strcmp(a->name,w1)) + break; + a=a->next; + } + + if (!a) + return str; + + for ( p=a->str; *p; p++) + { + if ( *p != '$' ) + { + ADD(p1,*p); + continue; + } + + dollar=1; + p++; + + if (isdigit(*p)) + { + ADDSTR(&p1,word(str,(*p)-'0'+1)); + continue; + } + + switch (*p) + { + + case '\0': + case '$': ADD(p1,'$');continue; + case '*': ADDSTR(&p1,args);continue; + default: ADD(p1,'$');ADD(p1,*p);continue; + } + } + + if (!dollar) + { + ADD(p1,' '); + ADDSTR(&p1,args); + } + + *p=0; + + return new; +} + +ifalias(char *cmd) +{ + String what; + ALIAS *a=firstalias; + + + strcpy(what,word(cmd,1)); + + while ( a!=NULL) + { + if (!strcmp(a->name,what)) + return 1; + a=a->next; + } + return 0; +} + + + +char *getprompt() +{ + + static String _prompt; + String tmp; + char *s; + + _prompt[0]=0; + + for(s=prompt;*s;s++) + switch (*s) + { + case '%': + switch (*++s) + { + + case 'H': + strcat(_prompt,iftp[frame].host); + break; + + case 'h': + strcpy(tmp,iftp[frame].host); + if (strchr(tmp,'.')!=NULL) *(char *)strchr(tmp,'.')=0; + strcat(_prompt,tmp); + break; + + case 'M': + gethostname(tmp, sizeof tmp); + strcat(_prompt,gethostbyname(tmp)->h_name); + break; + + case 'm': + gethostname(tmp, sizeof tmp); + strcpy(tmp,gethostbyname(tmp)->h_name); + if (strchr(tmp,'.')!=NULL) *(char *)strchr(tmp,'.')=0; + strcat(_prompt,tmp); + break; + + case 'u': + strcat(_prompt,iftp[frame].user); + break; + + case 'd': + strcat(_prompt,iftp[frame].pwd); + break; + + case 'D': + strcat(_prompt,(char *)getcwd(tmp,sizeof(tmp))); + break; + + case 'f': + sprintf(tmp,"%d",frame); + strcat(_prompt,tmp); + break; + + case 'p': + sprintf(tmp,"%d",(LINK==NULL)?0:LINK->port); + strcat(_prompt,tmp); + break; + + case 't': + + sprintf(tmp,"%d",(LINK==NULL)?0:LINK->timeout.tv_sec); + strcat(_prompt,tmp); + break; + + + case 'T': + + { + time_t t=time((time_t *)0); + struct tm *lt=localtime(&t); + sprintf(tmp,"%02d:%02d:%02d",lt->tm_hour, + lt->tm_min,lt->tm_sec); + strcat(_prompt,tmp); + } + break; + + case 'P': + + sprintf(tmp,"%d",getpid()); + strcat(_prompt,tmp); + break; + + default: + sprintf(tmp,"%%%c",*s); + strcat(_prompt,tmp); + break; + } + break; + + case '^': + + ++s; + if (isalpha(*s)) + { + sprintf(tmp,"%c",toupper(*s)-'A'+1); + strcat(_prompt,tmp); + } + break; + + default: + + sprintf(tmp,"%c",*s); + strcat(_prompt,tmp); + break; + } + return _prompt; +} + + +void noop() +{ + int i; + time_t curtime,save; + STATUS (*func1)(),(*func2)(),(*func3)(); + + + if (noopinterval==0) return; + + curtime = time((time_t *)0); + + signal(SIGALRM,noop); + + if (prevtime==0) + { + prevtime=curtime; + alarm(noopinterval); + return; + } + + if (curtime-prevtime < noopinterval) + { + alarm(prevtime+noopinterval-curtime); + return; + } + + printf("Waiting...");fflush(stdout); + + for (i=0;i<NFRAMES;i++) + { + if ( ftp[i]==NULL || FTPCMD(ftp[i]) == NULL || iftp[i].lock ) + continue; + + func1=ftp[i]->debug; ftp[i]->debug=NULL; + func2=ftp[i]->error; ftp[i]->error=NULL; + func3=ftp[i]->IO; ftp[i]->IO=NULL; + save = ftp[i]->timeout.tv_sec; + ftp[i]->timeout.tv_sec = nooptimeout; + + FtpCommand(ftp[i],"NOOP","",0,EOF); + + ftp[i]->timeout.tv_sec = save; + ftp[i]->debug=func1; + ftp[i]->error=func1; + ftp[i]->IO=func1; + + } + + alarm(noopinterval); + prevtime=curtime; + + for (i=0;i<10;i++) putchar(8),putchar(' '),putchar(8); + fflush(stdout); +} + + +setsignals() +{ + signal(SIGINT,intr); + signal(SIGQUIT,intr); + noop(); +} + +unsetsignals() +{ + signal(SIGALRM,SIG_IGN); + alarm(0); +} + + +int myhash(FTP *ftp,unsigned int chars) +{ + + if (hashmode) + { + if (chars==0) return ftp -> counter=0; + ftp -> counter += chars; + fprintf(stdout,"%10u bytes transfered\r",ftp -> counter); + fflush(stdout); + } + + if (!lastcmd) + { + noop(); + alarm(0); + } +} + + + +char *makefilename(char *f1, char *f2) +{ + char *p; + + if (*f2!=0) + return f2; + + if ( (p=strrchr(f1,'/'))!=NULL) + return p+1; + return f1; +} + +redir(char *cmdline) +{ + char *p=cmdline; + String result; + char *r=result; + + for ( ; *p ; p++ , r++ ) + { + if ( *p == '\\' ) + { + *r = * ++ p ; + continue; + } + + if ( *p == '>' || *p == '<' ) + { + String filename; + char *q=filename; + char c=*p; + + for (p++;isspace(*p)&&*p!=0;p++); + if (*p=='"') + { + for (p++; *p!='"' && *p!=0 ; p++,q++) *q=*p; + if (*p!='"') p++; + } + else + for (; !isspace(*p) && *p!=0 ; p++,q++) *q=*p; + + *q=0; + + if ( c == '>' ) + output(filename); + else + input(filename); + } + *r=*p; + } + *r=0; + strcpy(cmdline,result); +} + +int itty=-1,otty=-1; +FILE *is=NULL,*os=NULL; + + +input(char *filename) +{ + + if ((is=Ftpfopen(filename,"r"))==NULL) + { + perror(filename); + return; + } + + fflush(stdin); + itty=dup(0); + close(0); + dup2(fileno(is),0); + +} + +output(char *filename) +{ + + if ((os=Ftpfopen(filename,"w"))==NULL) + { + perror(filename); + return; + } + + fflush(stdout); + otty=dup(1); + close(1); + dup2(fileno(os),1); +} + +redirback() +{ + + if (itty!=-1) + { + fflush(stdin); + close(0); + Ftpfclose(is); + dup2(itty,0); + is=NULL; + itty=-1; + } + + if (otty!=-1) + { + fflush(stdout); + close(1); + Ftpfclose(os); + dup2(otty,1); + os=NULL; + otty=-1; + } +} + + +batch(char *filename) +{ + FILE *fp; + String tmp; + + if ((fp=fopen(filename,"r"))!=NULL) + { + + while ( fgets(tmp, sizeof tmp, fp) != NULL) + { + tmp[strlen(tmp)-1]=0; + execute(tmp); + if (tmp[0]) add_history(tmp); + } + fclose(fp); + } +} + + + + + + |