LVal parse_attr(char* str) { int i,j; char *name,*val; struct Cons tmp,*ret=&tmp,*cur=ret; struct opts* p; tmp.next=(LVal)NULL; for(i=0;str[i]!='\0';++i) { name=NULL,val=NULL; /*skip space*/ int pos=position_char_not(" \t\r\n",&str[i]); if(pos!=-1) { i+=pos; }else continue; /*attr name */ pos=position_char("\"'>/= \t\r\n",&str[i]); if(pos!=-1) name=subseq(&str[i],0,pos),i+=pos; /*skip space*/ pos=position_char_not(" \t\r\n",&str[i]); if(pos!=-1) i+=pos; if(!(name && str[i]=='=')) continue; cur->next=(LVal)attralloc();; p=(struct opts*)firstp((LVal)cur->next); p->name=name; /*skip space*/ pos=position_char_not(" \t\r\n",&str[++i]); if(pos!=-1) { i+=pos; switch(str[i]) { case '\'': j=position_char("'",&str[i+1]); if(j!=-1) { val=subseq(&str[i+1],0,j); i+=j+1; } break; case '"': for(j=1;str[i+j]!='"';++j) if(str[i+j]=='\\') ++j; val=subseq(&str[i],1,j); i+=j; break; default: pos=position_char(" \t\r\n",&str[i]); val=subseq(&str[i],0,pos); break; } p->value=val; } cur=(struct Cons *)cur->next; } return (LVal)ret->next; }
static size_t header_callback(char *buffer, size_t size,size_t nitems, int *opt) { int pos=-1,pos2,code=0; if(strncmp("HTTP",buffer,nitems<4?nitems:4)==0) { pos=position_char(" ",buffer); if(pos!=-1 && (pos2=position_char_not("0123456789",&buffer[pos+1]))!=-1) { char *num=subseq(&buffer[pos+1],0,pos2); code=atoi(num),s(num); if(verbose) fprintf(c_out, "http response:%d\n",code); } if(400<=code) return 0; /*invoke error for curl*/ }else if(strncmp("content-length:",downcase(buffer),nitems<15?nitems:15)==0) { pos=position_char(" ",buffer); if(pos!=-1 && (pos2=position_char_not("0123456789",&buffer[pos+1]))!=-1) { char *num=subseq(&buffer[pos+1],0,pos2); code=atoi(num),s(num); content_length=code; } } return nitems * size; }
char* determin_impl(char* impl) { char* version=NULL; int pos; cond_printf(1,"determin_impl:%s\n",impl); if(impl && (pos=position_char("/",impl))!=-1) { version=subseq(impl,pos+1,0); impl=subseq(impl,0,pos); }else { if(!impl) impl=get_opt("default.lisp",1); if(impl) { char* opt=s_cat(q(impl),q("."),q("version"),NULL); version=get_opt(opt,1); s(opt); } if(!impl) impl=DEFAULT_IMPL; impl=q(impl); if(version) version=q(version); } if(!version&&strcmp(impl,DEFAULT_IMPL)!=0) { cond_printf(1,"once!%s,%s\n",impl,version); if(!version) s(version); version=q("system"); } if(!(impl && version)) { char* cmd=cat(which(argv_orig[0]),verbose>0?(verbose>1?" -v -v":" -v"):""," setup",NULL); char* ret; if(impl) s(impl); impl=q(DEFAULT_IMPL); cond_printf(1,"cmd:%s\n",cmd); ret=system_(cmd); cond_printf(1,"ret:%s\n",ret); s(ret); char* path=s_cat(configdir(),q("config"),NULL); global_opt=load_opts(path),s(path);; version=get_opt(DEFAULT_IMPL".version",0); } return s_cat(impl,q("/"),version,NULL); }
char* which(char* cmd) { #ifndef HAVE_WINDOWS_H char* which_cmd=cat("command -v \"",cmd,"\"",NULL); #else if((cmd[0]=='.' && cmd[1]=='/')|| /* relative path */ position_char("/:",cmd)!=-1) { /* have no path element */ cmd=substitute_char('\\','/',q(cmd)); return truename(cmd); } char* which_cmd=cat("cmd /c where ",cmd,"",NULL); #endif cond_printf(1,"which cmd:%s\n",which_cmd); char* p=system_(which_cmd); cond_printf(1,"which result:%s\n",p); p=substitute_char('\0','\r',substitute_char('\0','\n',p)); char* p2=p?remove_char("\r\n",p):q(""); s(p),s(which_cmd); return p2; }
int sbcl_bin_expand(struct install_options* param) { char* impl=param->impl; char* version=q(param->version); int ret; char* home=configdir(); char* arch= arch_(param); char* archive=cat(impl,"-",version,"-",arch,".msi",NULL); char* log_path=cat(home,"impls",SLASH,"log",SLASH,impl,"-",version,"-",arch,SLASH,"install.log",NULL); char* dist_path; int pos=position_char("-",impl); if(pos!=-1) { impl=subseq(impl,0,pos); }else impl=q(impl); dist_path=cat(home,"src",SLASH,impl,"-",version,"-",arch,SLASH,NULL); printf("Extracting the msi archive. %s to %s\n",archive,dist_path); archive=s_cat(q(home),q("archives"),q(SLASH),archive,NULL); delete_directory(dist_path,1); ensure_directories_exist(dist_path); ensure_directories_exist(log_path); if(dist_path[strlen(dist_path)-1]=='\\') dist_path[strlen(dist_path)-1]='\0'; char* cmd=cat("msiexec.exe /a \"", archive, "\" targetdir=\"", dist_path, "\" /qn /lv ", "\"", log_path, "\"", NULL); cmd=cat("cmd /c \"",cmd,"\"",NULL); cond_printf(1,"msiexeccmd:%s\n",cmd); ret=System(cmd); s(impl); s(dist_path); s(log_path); s(archive); s(cmd),s(home),s(version),s(arch); return !ret; }
int install_help(int argc,char **argv,struct sub_command* cmd) { if(argc==1) { cond_printf(0,"Usage: %s install impl [OPTIONS]\n\nFor more details on impl specific options, type:\n %s help install impl\n\n" "Candidates impls for installation are:\n",argv_orig[0],argv_orig[0]); char* install=lispdir(); LVal d=directory(install),v=d; for(;v;v=Next(v)) { char* str=firsts(v); if(str[strlen(str)-1]!='/') { int p=position_char(".",str); if(p!=-1) { char *sub=subseq(str,0,p); if(p>=8/*strlen("install-")*/ && strncmp(str,"install-",8)==0) printf("%s\n",sub+8); s(sub); } } } sL(d); }else if(argc==2) { int i,j,argc_; char** tmp; char* install_ros=s_cat2(lispdir(),q("install.ros")); tmp=(char**)alloc(sizeof(char*)*(argc+9)); i=0; tmp[i++]=q("--"); tmp[i++]=install_ros; tmp[i++]=q("help"); tmp[i++]=q(argv[1]); for(j=2;j<argc;tmp[i++]=q(argv[j++])); argc_=i; for(i=0;i<argc_;i+=proccmd(argc_-i,&tmp[i],top_options,top_commands)); for(j=0;j<argc_;s(tmp[j++])); dealloc(tmp); } return 0; }
int cmd_run_star(int argc,char **argv,struct sub_command* cmd) { int ret=1; char* config=configdir(); set_opt(&local_opt,"quicklisp",s_escape_string(cat(config,"impls",SLASH,"ALL",SLASH,"ALL",SLASH,"quicklisp",SLASH,NULL)),0); set_opt(&local_opt,"argv0",argv_orig[0],0); set_opt(&local_opt,"wargv0",which(argv_orig[0]),0); set_opt(&local_opt,"homedir",config,0); if(rc) { char* init=s_cat(configdir(),q("init.lisp"),NULL); #ifdef _WIN32 char* etc=""; #else char* etc="/etc/rosrc"; #endif char* current=get_opt("program",0); char *path,*would; if(file_exist_p(init)) { path=cat("(:load \"",init,"\")",NULL); would=cat(path,current?current:"",NULL); s(current); set_opt(&local_opt,"program",would,0); s(path); } s(init); current=get_opt("program",0); if(file_exist_p(etc)) { path=cat("(:load \"",etc,"\")",NULL); would=cat(path,current?current:"",NULL); set_opt(&local_opt,"program",would,0); } } char*lisp=get_opt("lisp",1); if(!lisp) lisp=get_opt("*lisp",0); set_opt(&local_opt,"impl",determin_impl(lisp),0); char** arg=NULL; int i; char* wrap=get_opt("wrap",1); { struct sub_command cmd; int i; char *_= get_opt("impl",0); i=position_char("/",_); cmd.name=subseq(_,0,i); cmd.short_name=subseq(_,i+1,0); for(i=0;i<sizeof(impls_to_run)/sizeof(struct run_impl_t);++i) if(strcmp(impls_to_run[i].name,cmd.name)==0) { arg=impls_to_run[i].impl(argc,argv,&cmd); break; } s((char*)cmd.name),s((char*)cmd.short_name); } if(wrap) arg[0]=q(wrap); if(arg && file_exist_p(arg[1])) { char* opts=sexp_opts(local_opt); setenv("ROS_OPTS",opts,1); if(verbose&1 ||testing) { fprintf(stderr,"args "); for(i=0;arg[i]!=NULL;++i) fprintf(stderr,"%s ",arg[i]); fprintf(stderr,"\nROS_OPTS %s\n",getenv("ROS_OPTS")); if(testing) s(opts),exit(EXIT_SUCCESS); } s(opts); #ifdef _WIN32 { char* cmd=q(arg[wrap?0:1]); for(i=wrap?1:2;arg[i]!=NULL;++i) { cmd=s_cat(cmd,q(" "),q("\""),escape_string(arg[i]),q("\""),NULL); } SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); exit(System(cmd)); s(cmd); } #else execvp(arg[wrap?0:1],&(arg[wrap?0:1])); #endif }else fprintf(stderr,"%s is not installed.stop.\n",get_opt("impl",0)); s(config); return ret; }
int cmd_install(int argc,char **argv,struct sub_command* cmd) { install_cmds *cmds=NULL; struct install_options param; quicklisp=1; param.os=uname(); param.arch=uname_m(); param.arch_in_archive_name=0; param.expand_path=NULL; if(argc!=1) { int ret=1,k; for(k=1;k<argc;++k) { int i,pos; param.impl=argv[k]; pos=position_char("/",param.impl); if(pos!=-1) { param.version=subseq(param.impl,pos+1,0); param.impl=subseq(param.impl,0,pos); }else { param.version=NULL; param.impl=q(param.impl); } for(install_impl=NULL,i=0;i<sizeof(impls_to_install)/sizeof(struct install_impls*);++i) { struct install_impls* j=impls_to_install[i]; if(strcmp(param.impl,j->name)==0) { install_impl=j; } } if(install_impl) { for(cmds=install_impl->call;*cmds&&ret;++cmds) ret=(*cmds)(¶m); if(ret) { // after install latest installed impl/version should be default for 'run' struct opts* opt=global_opt; struct opts** opts=&opt; char* home=configdir(); char* path=cat(home,"config",NULL); char* v=cat(param.impl,".version",NULL); char* version=param.version; if(!install_impl->util) { int i; for(i=0;version[i]!='\0';++i) if(version[i]=='-') version[i]='\0'; set_opt(opts,"default.lisp",param.impl,0); set_opt(opts,v,version,0); save_opts(path,opt); } s(home),s(path),s(v); } }else { char* lisp_path=lispdir(); int i,j,argc_; char** tmp; char* install_ros=s_cat2(lisp_path,q("install.ros")); if(verbose&1) { fprintf(stderr,"%s is not implemented internal. %s argc:%d\n",param.impl,install_ros,argc); for(i=0;i<argc;++i) fprintf(stderr,"%s:",argv[i]); fprintf(stderr,"\n"); } tmp=(char**)alloc(sizeof(char*)*(argc+9)); i=0; tmp[i++]=q("--"); tmp[i++]=install_ros; tmp[i++]=q("install"); tmp[i++]=q(argv[1]); for(j=2;j<argc;tmp[i++]=q(argv[j++])); argc_=i; if(verbose&1) { int j; fprintf(stderr,"argc_=%d",argc_); for(j=0;j<argc_;++j) fprintf(stderr,"argv[%d]=%s,",j,tmp[j]); } for(i=0;i<argc_;i+=proccmd(argc_-i,&tmp[i],top_options,top_commands)); for(j=0;j<argc_;s(tmp[j++])); dealloc(tmp); return 0; } if(param.version)s(param.version); s(param.impl),s(param.arch),s(param.os); s(param.expand_path); if(!ret) exit(EXIT_FAILURE); } }else { char* tmp[]={"help","install"}; proccmd(2,tmp,top_options,top_commands); exit(EXIT_SUCCESS); } return 0; }
/* return value: * 0 success * -1 fopen failed * -2 curl initialization failed * -3 scheme is neither http nor https * -4 faild to parse the URL (InternetCrackUrl) (windows) * -5 https responce status is not HTTP_STATUS_OK (windows) * -6 HttpQueryInfo failed (windows) * -7 rename failure */ int download_simple (char* uri,char* path,int opt) { FILE *bodyfile; char* path_partial=cat(path,".partial",NULL); bodyfile = fopen(path_partial,"wb"); if (bodyfile == NULL) { s(path_partial); return -1; } c_out=0==(download_opt=opt)?stderr:stdout; #ifndef HAVE_WINDOWS_H CURL *curl; CURLcode res=!CURLE_OK; curl = curl_easy_init(); if(curl) { char* current=get_opt("ros.proxy",1); if(current) { /*<[protocol://][user:password@]proxyhost[:port]>*/ char *reserve=current,*protocol=NULL,*userpwd=NULL,*port=NULL,*uri=NULL; int pos=position_char("/",current); if(pos>0 && current[pos-1]==':' && current[pos+1]=='/') protocol=current,current[pos-1]='\0',current=current+pos+2; pos=position_char("@",current); if(pos!=-1) userpwd=current,current[pos]='\0',current=current+pos+1; pos=position_char(":",current); if(pos!=-1) current[pos]='\0',port=current+pos+1,uri=current; curl_easy_setopt(curl, CURLOPT_PROXY, uri); if(port) curl_easy_setopt(curl, CURLOPT_PROXYPORT,atoi(port)); if(userpwd) curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd); s(reserve); } count=0,content_length=0; curl_easy_setopt(curl, CURLOPT_URL, uri); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); curl_easy_setopt(curl,CURLOPT_WRITEDATA,bodyfile); res = curl_easy_perform(curl); if(res != CURLE_OK && verbose) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); fclose(bodyfile); } if(res != CURLE_OK) return -2; #else URL_COMPONENTS u; TCHAR szHostName[4096]; TCHAR szUrlPath[4096]; u.dwStructSize = sizeof(u); u.dwSchemeLength = 1; u.dwHostNameLength = 4096; u.dwUserNameLength = 1; u.dwPasswordLength = 1; u.dwUrlPathLength = 4096; u.dwExtraInfoLength = 1; u.lpszScheme = NULL; u.lpszHostName = szHostName; u.lpszUserName = NULL; u.lpszPassword = NULL; u.lpszUrlPath = szUrlPath; u.lpszExtraInfo = NULL; if(!InternetCrackUrl(uri,(DWORD)strlen(uri),0,&u)) { fclose(bodyfile); return -4; } HINTERNET hSession = InternetOpen("WinInet",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); HINTERNET hConnection = InternetConnect(hSession,szHostName,u.nPort,NULL,NULL,INTERNET_SERVICE_HTTP,0,0); DWORD dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE; if(INTERNET_SCHEME_HTTP == u.nScheme) { }else if( INTERNET_SCHEME_HTTPS == u.nScheme ) { dwFlags = dwFlags | INTERNET_FLAG_SECURE| INTERNET_FLAG_IGNORE_CERT_DATE_INVALID| INTERNET_FLAG_IGNORE_CERT_CN_INVALID; }else { fclose(bodyfile); return -3; } HINTERNET hRequest = HttpOpenRequest(hConnection,"GET",szUrlPath,NULL,NULL,NULL,dwFlags,0); HttpSendRequest(hRequest,NULL,0,NULL,0); DWORD dwStatusCode,dwContentLen; DWORD dwLength = sizeof(DWORD); if(HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,&dwContentLen,&dwLength,0)) content_length=dwContentLen; if(!HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwLength,0)) { fclose(bodyfile); return -6; } if(HTTP_STATUS_OK != dwStatusCode) { fclose(bodyfile); return -5; } char pData[10000]; DWORD dwBytesRead = 1; count=0; while (dwBytesRead) { InternetReadFile(hRequest, pData, 99, &dwBytesRead); pData[dwBytesRead] = 0; write_data(pData,dwBytesRead,1,bodyfile); } fclose(bodyfile); #endif fprintf(c_out, "\n"); int ret=rename_file(path_partial,path); s(path_partial); return ret?0:-7; }
int download_simple (char* uri,char* path,int opt) { FILE *bodyfile; char* path_partial=cat(path,".partial",NULL); bodyfile = fopen(path_partial,"wb"); if (bodyfile == NULL) { s(path_partial); return 1; } download_out=0==(download_opt=opt)?stderr:stdout; CURL *curl; CURLcode res=!CURLE_OK; curl = curl_easy_init(); if(curl) { char* current=get_opt("ros.proxy",1); int lenuri=strlen(uri); int https=(lenuri>5 && strncmp("https",uri,5)==0); int httponly= get_opt("proxy.http.only",0) && strcmp(get_opt("proxy.http.only",0),"1")==0; if(current&& ((https && !httponly) || !https)) { /*<[protocol://][user:password@]proxyhost[:port]>*/ char *reserve,*protocol=NULL,*userpwd=NULL,*port=NULL,*uri=NULL; int pos=position_char("/",current); reserve=current=q_(current); if(pos>0 && current[pos-1]==':' && current[pos+1]=='/') protocol=current,current[pos-1]='\0',current=current+pos+2; pos=position_char("@",current); if(pos!=-1) userpwd=current,current[pos]='\0',current=current+pos+1; pos=position_char(":",current); if(pos!=-1) current[pos]='\0',port=current+pos+1,uri=current; cond_printf(1,"proxy uri=%s",uri); curl_easy_setopt(curl, CURLOPT_PROXY, uri); if(port) { cond_printf(1," port=%s",port); curl_easy_setopt(curl, CURLOPT_PROXYPORT,atoi(port)); } if(userpwd) curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd); cond_printf(1,"\n"); s(reserve); } download_count=0,content_length=0; curl_easy_setopt(curl, CURLOPT_URL, uri); curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE_STRING); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); curl_easy_setopt(curl,CURLOPT_WRITEDATA,bodyfile); res = curl_easy_perform(curl); if(res != CURLE_OK && verbose) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); fclose(bodyfile); } if(res != CURLE_OK) return 2; fprintf(download_out, "\n"); int ret=rename_file(path_partial,path); s(path_partial); return ret?0:7; }
LVal parse_tags(FILE* fp,LVal before,int mode) { LVal current=tagalloc(); char str[2]={'\0','\0'}; int c,i=0; char* buf=q(""); switch(mode) { case 0: /* wait for '<' */ ((struct tag*)firstp(current))->type=0; while((c=fgetc(fp))!=EOF) { if(c=='<') { if(strlen(buf)==0) { tagfree(current); s(buf); return parse_tags(fp,before,1); }else { ((struct Cons*)current)->next=parse_tags(fp,current,1); s(buf); return current; } }else str[0]=c,buf=s_cat2(buf,q(str)); } break; case 1: /* wait for '>' */ ((struct tag*)firstp(current))->type=0; while((c=fgetc(fp))!=EOF) { if(i==0) { if(c=='/') ((struct tag*)firstp(current))->type=2; else { ((struct tag*)firstp(current))->type=1; str[0]=c; buf=s_cat2(buf,q(str)); } ++i; continue; } if(c=='>') { char *buf2; if(((struct tag*)firstp(current))->type==2) { int pos=position_char(" \t\r\n",buf); if(pos!=-1) { buf2=subseq(buf,0,pos); s(buf); buf=buf2; ((struct tag*)firstp(current))->name=q(buf); }else { ((struct tag*)firstp(current))->name=buf; buf=q(""); } }else if(((struct tag*)firstp(current))->type==1) { int pos=position_char(" \t\r\n",buf); if(pos!=-1) { ((struct tag*)firstp(current))->name=subseq(buf,0,pos); buf2=subseq(buf,pos,0); ((struct tag*)firstp(current))->attr=(struct Cons*)parse_attr(buf2); s(buf); buf=buf2; }else { ((struct tag*)firstp(current))->name=buf; buf=q(""); } } if(strcmp(((struct tag*)firstp(current))->name,"script")==0) { ((struct Cons*)current)->next=parse_tags(fp,current,2); }else{ ((struct Cons*)current)->next=parse_tags(fp,current,0); } s(buf); return current; }else { str[0]=c; buf=s_cat2(buf,q(str)); } ++i; } break; case 2: /* wait for '</' */ ((struct tag*)firstp(current))->type=0; while((c=fgetc(fp))!=EOF) { if(c=='<') { if((c=fgetc(fp))!=EOF && c=='/') { ungetc('/',fp); if(strlen(buf)==0) { tagfree(current); s(buf); return parse_tags(fp,current,1); }else { ((struct Cons*)current)->next=parse_tags(fp,current,1); s(buf); return current; } } ungetc('/',fp); }else { str[0]=c; buf=s_cat2(buf,q(str)); } } break; } s(buf); return current; }