/** xurl.c - (c) 1994 Copyright by John R. Punin * * ASHE Editor of the HTML. * * This file has the routines to parse the url into a structure. * These routines are based on the code written by students of the * topic WWW. * * John R. Punin March -12 - 1994 * */ #include "xhtml.h" #include "xurl.h" void initialize_url(GURL *url) { url->ws_protocol=NULL; url->ws_user=NULL; url->ws_password=NULL; url->ws_host=NULL; url->ws_port=NULL; url->ws_path=NULL; url->ws_name=NULL; url->ws_rest=NULL; url->wc_jump=NULL; } int identify (char *furl) { if (strncmp(furl,"ftp://",6) == 0) return(UFTP); if (strncmp(furl,"http://",7) == 0) return(UHTTP); if (strncmp(furl,"gopher://",9) == 0) return(UGOPHER); if (strncmp(furl,"mailto:",7) == 0) return(UMAILTO); if (strncmp(furl,"news:",5) == 0) return(UNEWS); if (strncmp(furl,"nntp://",7) == 0) return(UNNTP); if (strncmp(furl,"telnet://",9) == 0) return(UTELNET); if (strncmp(furl,"wais://",7) == 0) return(UWAIS); if (strncmp(furl,"file:",5) == 0) return(UFILE); if (strncmp(furl,"prospero://",11) == 0) return(UPROSPERO); return(0); } int reserved_char(char c) { if((c == '=')||(c == ';')||(c == '/') || (c == '#') || (c == '?') || (c == ':') || (c == ' ')) return 1; return 0; } char * get_prot(char *furl, int code) { switch(code) { case UFTP: return(&(furl[6])); case UHTTP: return(&(furl[7])); case UMAILTO: return(&(furl[7])); case UFILE: return(&(furl[5])); case UGOPHER: return(&(furl[9])); case UNEWS: return(&(furl[5])); case UTELNET: return(&(furl[9])); case UWAIS: return(&(furl[7])); case UNNTP: return(&(furl[7])); case UPROSPERO: return(&(furl[11])); } return NULL; } char * get_login(char *furl, GURL *url) { int i, len = strlen(furl); for(i=0;iws_user = malloc(i+2); strncpy(url->ws_user, furl,i); url->ws_user[i]='\0'; if(furl[i]==':') { furl=&(furl[i+1]); len = strlen(furl); for(i = 0; i< len ; i++) { if(furl[i]=='@') break; } if(i < len) { url->ws_password = malloc(i+2); strncpy(url->ws_password, furl, i); url->ws_password[i]='\0'; } } if(furl[i]!='@') return NULL; else return (&(furl[i+1])); } return furl; } char * get_host(char *furl, GURL *url) { char *wp_furl1 = NULL; int wi_long, wi_long1,i; wi_long = 0; wi_long1 = -1; wi_long = strlen(furl); for (i = 0; i < wi_long; i++) { if ((furl[i] == ':')||(furl[i] == '/')) { wi_long1 = i; wp_furl1 = &furl[i]; break; } } if (wi_long1 != -1) { url->ws_host = malloc(wi_long1+2); strncpy(url->ws_host,furl,wi_long1); url->ws_host[wi_long1]='\0'; } else { url->ws_host = malloc(wi_long); strcpy(url->ws_host,furl); } return(wp_furl1); } char * get_port(char *furl, GURL *url) { char *wp_furl1=NULL; int wi_long,wi_long1=-1,i; if(furl[0]!=':') return furl; furl = &(furl[1]); wi_long = strlen(furl); for (i = 0; i < wi_long; i++) { if (furl[i] == '/') { wi_long1 = i; wp_furl1 = &furl[i]; break; } } if (wi_long1 != -1) { url->ws_port = malloc(wi_long1+2); strncpy(url->ws_port,furl,wi_long1); url->ws_port[wi_long1]='\0'; } else { url->ws_port = malloc(wi_long+2); strcpy(url->ws_port,furl); } return(wp_furl1); } char * get_path(char *furl, GURL *url) { char *wp_furl1=NULL; int wi_long,wi_long1=-1,i; if(furl[0]!='/') return furl; wi_long = strlen(furl); for (i = 0; i < wi_long; i++) { if ((furl[i] == '?')||(furl[i]==';')) { wi_long1 = i; wp_furl1 = &(furl[i]); break; } } if (wi_long1 != -1) { url->ws_path = malloc(wi_long1+2); strncpy(url->ws_path,furl,wi_long1); url->ws_path[wi_long]='\0'; } else { url->ws_path = malloc(wi_long+2); strcpy(url->ws_path,furl); } return(wp_furl1); } char * get_ftp_rest(char *furl, GURL *url) { if(furl[0]!=';') return furl; url->ws_rest = strdup(furl); return NULL; } char * get_http_rest(char *furl, GURL *url) { if(furl[0]!='?') return furl; url->ws_rest = strdup(furl); return NULL; } char * get_mailto_rest(char *furl, GURL *url) { int len,i; len = strlen(furl); for(i = 0; iws_rest = strdup(furl); return NULL; } return furl; } char * get_news_rest(char *furl, GURL *url) { int len, i; len = strlen(furl); for(i = 0; iws_rest = strdup(furl); return NULL; } return furl; } void get_rest(char *furl, GURL *url) { url->ws_rest = strdup(furl); } int val_ftp(char *furl, GURL *url) { url->ws_protocol = malloc(5); strcpy(url->ws_protocol,"ftp"); url->protocol = UFTP; furl = get_prot(furl,UFTP); if(furl) furl = get_login(furl,url); /* login */ if(furl) furl = get_host(furl,url); /* host */ if(furl) furl = get_port(furl,url); if(furl) furl = get_path(furl,url); if(furl) furl = get_ftp_rest(furl, url); if(furl) return ERROR_FTP; else return 0; } int val_http(char *furl, GURL *url) { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"http"); url->protocol = UHTTP; furl = get_prot(furl,UHTTP); if(furl) furl = get_host(furl,url); if(furl) furl = get_port(furl,url); if(furl) furl = get_path(furl,url); if(furl) furl = get_http_rest(furl,url); if(furl) return ERROR_HTTP; else return 0; } int val_mailto(char *furl, GURL *url) { url->ws_protocol = malloc(8); strcpy(url->ws_protocol,"mailto"); url->protocol = UMAILTO; furl = get_prot(furl,UMAILTO); furl = get_mailto_rest(furl,url); if (furl) return(ERROR_MAILTO); else return 0; } int val_file(char *furl, GURL *url) { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"file"); url->protocol = UFILE; furl = get_prot(furl,UFILE); if(furl && strlen(furl) > 3) { if(furl[0]=='/' && furl[1]=='/') furl = get_host(&(furl[2]),url); } if(furl) furl = get_path(furl,url); if(furl) furl = get_ftp_rest(furl,url); /* ftp equivalent */ if (furl) return(ERROR_FILE); else return 0; } int val_gopher(char *furl, GURL *url) { url->ws_protocol = malloc(8); strcpy(url->ws_protocol,"gopher"); url->protocol = UGOPHER; furl = get_prot(furl,UGOPHER); if(furl) furl = get_host(furl,url); if(furl) furl = get_path(furl,url); if (furl) return(ERROR_GOPHER); else return 0; } int val_news(char *furl, GURL *url) { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"news"); url->protocol = UNEWS; furl = get_prot(furl,UNEWS); if(furl) furl = get_news_rest(furl,url); if (furl) return(ERROR_NEWS); else return 0; } int val_telnet(char *furl, GURL *url) { url->ws_protocol = malloc(8); strcpy(url->ws_protocol,"telnet"); url->protocol = UTELNET; furl = get_prot(furl,UTELNET); if(furl) furl = get_login(furl,url); /* login */ if(furl) furl = get_host(furl,url); /* host */ if(furl) furl = get_port(furl,url); if (furl) return(ERROR_TELNET); else return 0; } int val_wais(char *furl, GURL *url) { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"wais"); url->protocol = UWAIS; furl = get_prot(furl,UWAIS); if(furl) furl = get_host(furl,url); /* host */ if(furl) furl = get_port(furl,url); if(furl) furl = get_path(furl,url); if(furl) furl = get_http_rest(furl, url); if (furl) return(ERROR_WAIS); else return 0; } int val_prospero(char *furl, GURL *url) { url->ws_protocol = malloc(10); strcpy(url->ws_protocol,"prospero"); url->protocol = UPROSPERO; furl = get_prot(furl,UPROSPERO); if(furl) furl = get_host(furl,url); /* host */ if(furl) furl = get_port(furl,url); if(furl) furl = get_path(furl,url); if (furl) return(ERROR_PROSPERO); else return 0; } int val_nntp(char *furl, GURL *url) { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"nntp"); url->protocol = UNNTP; furl = get_prot(furl,UNNTP); if(furl) furl = get_news_rest(furl,url); if (furl) return(ERROR_NNTP); else return 0; } int val_unknown(char *furl, GURL *url) { int i,len=strlen(furl); if(len==0) return ERROR_FILE; for(i=0;iws_protocol = malloc(i+2); strncpy(url->ws_protocol,furl,i); url->protocol = UNKNOWN; url->ws_protocol[i]='\0'; get_rest(&(furl[i+1]),url); } else { url->ws_protocol = malloc(6); strcpy(url->ws_protocol,"file"); url->protocol = UFILE; furl = get_path(furl,url); if(furl) get_rest(furl,url); } return 0; } int recognize_url(char *furl,GURL *url) { int error = 0; switch (identify(furl)) { case UFTP: /* Ftp Protocol */ error = val_ftp(furl,url); break; case UHTTP: /* HTTP Protocol */ error = val_http(furl,url); break; case UGOPHER: /* Gopher Protocol */ error = val_gopher(furl,url); break; case UMAILTO: /* Mailto Protocol */ error = val_mailto(furl,url); break; case UNEWS: /* News Protocol */ error = val_news(furl,url); break; case UNNTP: /* NNTP Protocol */ error = val_nntp(furl,url); break; case UTELNET: /* Telnet Protocol */ error = val_telnet(furl,url); break; case UWAIS: /* Wais Protocol */ error = val_wais(furl,url); break; case UFILE: /* File Protocol */ error = val_file(furl,url); break; case UPROSPERO: /* Prospero Protocol */ error = val_prospero(furl,url); break; default: /* Unknown Protocol */ error = val_unknown(furl,url);; break; } return error; } void print_url(GURL *url) { printf("\nurl->ws_protocol: %s",url->ws_protocol); printf("\nurl->ws_user : %s",url->ws_user); printf("\nurl->ws_password : %s",url->ws_password); printf("\nurl->ws_host : %s",url->ws_host); printf("\nurl->ws_port : %s",url->ws_port); printf("\nurl->ws_path : %s",url->ws_path); printf("\nurl->ws_name : %s",url->ws_name); printf("\nurl->ws_rest : %s\n",url->ws_rest); } void delete_url(GURL *url) { if(url->ws_protocol) free(url->ws_protocol); if(url->ws_user) free(url->ws_user); if(url->ws_password) free(url->ws_password); if(url->ws_host) free(url->ws_host); if(url->ws_port) free(url->ws_port); if(url->ws_path) free(url->ws_path); if(url->ws_name) free(url->ws_name); if(url->ws_rest) free(url->ws_rest); } char * suppress_dots(char *file) { int len = strlen(file); int i=0; int find=0, sind=0, tind=0; i=1; while(1) { if(file[0]!='/') return NULL; if(len < 4) return (strdup(file)); if((file[1]=='.')&&(file[2]=='.')&&(file[3]=='/')) return NULL; while(file[i]!='/'&& i< len) i++; if(i==len) return(strdup(file)); sind = i; if((file[sind+1]=='.')&&(file[sind+2]=='.')&&(file[sind+3]=='/')) { char *tstr = strdup(file); tind = sind + 4; strcpy(&(file[find+1]),&(tstr[tind])); free(tstr); find = 0; i=0; len = strlen(file); } else { i=sind+1; find = sind; } } } /* Get a directory from a File name */ char * getdirectory (char *fname) { int i,j,len=strlen(fname); char *path=NULL; if(len!=0) { for(i=len-1;i>=0;i--) if(fname[i]=='/') break; if(i!=0) { path = XtMalloc(len+2); for(j=0;j<=i;j++) path[j]=fname[j]; path[j]='\0'; } } return(path); } String binding_relative_url(String url_rel,HTMLED *he,String directory,int *isfile) { String href=NULL; GURL *surl = (GURL *)malloc(sizeof(GURL)); int code; initialize_url(surl); code = recognize_url(url_rel,surl); if((code == 0) && !strcmp(surl->ws_protocol,"file")) { /* We should check if url is absolute or not */ /* Not implemented */ if(url_rel[0]!='/') { href = XtMalloc(strlen(directory)+strlen(url_rel)+5); sprintf(href,"%s%s",directory,url_rel); } else if(url_rel[0]=='/') { href = strdup(url_rel); } } else { href = strdup(url_rel); } *isfile = surl->protocol; /* Used Protocol */ delete_url(surl); free(surl); return href; } char * get_url_file(HTMLED *he,char *url_rel,String directory,int *isfile) { String oref,href,name,fhref; oref = binding_relative_url(url_rel,he,directory,isfile); strip_href(oref,&href,&name); if(oref) XtFree(oref); if(name) XtFree(name); fhref = suppress_dots(href); if(fhref) { XtFree(href); return fhref; } else return href; } void strip_href(char *ohref,char **href, char**name) { int len=0; int i; *href = NULL; *name = NULL; if(ohref!=NULL) len = strlen(ohref); if(len!=0) { *href = XtMalloc(len+2); *name = XtMalloc(len+2); (*name)[0]='\0'; for(i=len-1;i>=0;i--) if(ohref[i]=='#') break; strcpy(*href,ohref); if((i>=0)||((i==0)&&((*href)[0]=='#'))) { (*href)[i]='\0'; strcpy(*name,&(ohref[i+1])); } } }