Exemple #1
0
/* Pseudo-key (lien_url structure) hash function */
static inthash_keys key_adrfil_hashes_generic(void *arg, const char *value_, 
                                              const int former) {
  hash_struct *const hash = (hash_struct*) arg;
  const lien_url*const lien = (lien_url*) value_;
  const char *const adr = !former ? lien->adr : lien->former_adr;
  const char *const fil = !former ? lien->fil : lien->former_fil;
  const char *const adr_norm = adr != NULL ? 
    ( hash->normalized  ? jump_normalized(adr) : jump_identification(adr) )
    : NULL;

  // copy address
  assertf(adr_norm != NULL);
  strcpy(hash->normfil, adr_norm);

  // copy link
  assertf(fil != NULL);
  if (hash->normalized) {
    fil_normalized(fil, &hash->normfil[strlen(hash->normfil)]);
  } else {
    strcpy(&hash->normfil[strlen(hash->normfil)], fil);
  }

  // hash
  return inthash_hash_value(hash->normfil);
}
Exemple #2
0
/* Pseudo-key (lien_url structure) comparison function */
static int key_adrfil_equals_generic(void *arg, const char *a_, const char *b_, 
                                     const int former) {
  hash_struct *const hash = (hash_struct*) arg;
  const int normalized = hash->normalized;
  const lien_url*const a = (lien_url*) a_;
  const lien_url*const b = (lien_url*) b_;
  const char *const a_adr = !former ? a->adr : a->former_adr;
  const char *const b_adr = !former ? b->adr : b->former_adr;
  const char *const a_fil = !former ? a->fil : a->former_fil;
  const char *const b_fil = !former ? b->fil : b->former_fil;
  const char *ja;
  const char *jb;

  // safety
  assertf(a_adr != NULL);
  assertf(b_adr != NULL);
  assertf(a_fil != NULL);
  assertf(b_fil != NULL);

  // skip scheme and authentication to the domain (possibly without www.)
  ja = normalized ? jump_normalized(a_adr) : jump_identification(a_adr);
  jb = normalized ? jump_normalized(b_adr) : jump_identification(b_adr);
  assertf(ja != NULL);
  assertf(jb != NULL);
  if (strcasecmp(ja, jb) != 0) {
    return 0;
  }

  // now compare pathes
  if (normalized) {
    fil_normalized(a_fil, hash->normfil);
    fil_normalized(b_fil, hash->normfil2);
    return strcmp(hash->normfil, hash->normfil2) == 0;
  } else {
    return strcmp(a_fil, b_fil) == 0;
  }
}
void COptionTab10::Onproxyconfigure() 
{
  CProxyId proxy;
  char adr[256];
  CString s;
  GetDlgItemText(IDC_portprox,s);
  proxy.m_proxport=s;
  GetDlgItemText(IDC_prox,s);
  strcpybuff(adr,s);
  proxy.m_proxadr=jump_identification(adr);
  if (jump_identification(adr)!=adr) {
    char user_pass[256]; user_pass[0]='\0';
    char* a;
    size_t nsize = (size_t) ( ( jump_identification(adr) - adr ) - 1 );
    strncatbuff(user_pass,adr,nsize);
    a=strchr(user_pass,':');
    if (a)
      *a='\0';
    else
      a=user_pass+strlen(user_pass);
    proxy.m_proxlogin=user_pass;
    proxy.m_proxpass=a+1;
  }
  if (proxy.DoModal() == IDOK) {
    if (proxy.m_proxlogin.GetLength()==0) {
      SetDlgItemTextCP(this, IDC_prox,proxy.m_proxadr);
      m_ctl_pwdhide.SetCheck(0);
      OnPwdhide();
    } else {
      SetDlgItemTextCP(this, IDC_prox,proxy.m_proxlogin+":"+proxy.m_proxpass+"@"+proxy.m_proxadr);
      m_ctl_pwdhide.SetCheck(1);
      OnPwdhide();
    }
    SetDlgItemTextCP(this, IDC_portprox,proxy.m_proxport);
  }
}
Exemple #4
0
char *bauth_prefix(char *prefix, char *adr, char *fil) {
  char *a;

  strcpybuff(prefix, jump_identification(adr));
  strcatbuff(prefix, fil);
  a = strchr(prefix, '?');
  if (a)
    *a = '\0';
  if (strchr(prefix, '/')) {
    a = prefix + strlen(prefix) - 1;
    while(*a != '/')
      a--;
    *(a + 1) = '\0';
  }
  return prefix;
}
Exemple #5
0
// forme à partir d'un lien et du contexte (origin_fil et origin_adr d'où il est tiré) adr et fil
// [adr et fil sont des buffers de 1ko]
// 0 : ok
// -1 : erreur
// -2 : protocole non supporté (ftp)
int ident_url_relatif(const char *lien,const char* origin_adr,const char* origin_fil,char* adr,char* fil) {
  int ok=0;
  int scheme=0;

  adr[0]='\0'; fil[0]='\0';    //effacer buffers

  // lien non vide!
  if (strnotempty(lien)==0) return -1;    // erreur!

  // Scheme?
  {
    const char* a=lien;
    while (isalpha((unsigned char)*a))
      a++;
    if (*a == ':')
      scheme=1;
  }

  // filtrer les parazites (mailto & cie)
  // scheme+authority (//)
  if (
               (strfield(lien,"http://"))        // scheme+//
            || (strfield(lien,"file://"))   // scheme+//
            || (strncmp(lien,"//",2)==0)    // // sans scheme (-> default)
       ) {
    if (ident_url_absolute(lien,adr,fil)==-1) {        
      ok=-1;    // erreur URL
    }
  }
  else if (strfield(lien,"ftp://")) {
    // Note: ftp:foobar.gif is not valid
    if (ftp_available()) {     // ftp supporté
      if (ident_url_absolute(lien,adr,fil)==-1) {        
        ok=-1;    // erreur URL
      }
    } else {
      ok=-2;  // non supporté
    }
#if HTS_USEMMS
	} else if (strfield(lien,"mms://")) {
		if (ident_url_absolute(lien,adr,fil)==-1) {        
			ok=-1;    // erreur URL
		}
#endif
#if HTS_USEOPENSSL
  } else if (strfield(lien,"https://")) {
    if (SSL_is_available) {
      // Note: ftp:foobar.gif is not valid
      if (ident_url_absolute(lien,adr,fil)==-1) {        
        ok=-1;    // erreur URL
      }
    } else {
      ok=-1;
    }
#endif
  } else if ((scheme) && (
    (!strfield(lien,"http:"))
    && (!strfield(lien,"https:"))
    && (!strfield(lien,"ftp:"))
#if HTS_USEMMS
    && (!strfield(lien,"mms:"))
#endif
    )) {
    ok=-1;      // unknown scheme
  } else {    // c'est un lien relatif
    // On forme l'URL complète à partie de l'url actuelle
    // et du chemin actuel si besoin est.
    
    // copier adresse
    if (((int) strlen(origin_adr)<HTS_URLMAXSIZE) && ((int) strlen(origin_fil)<HTS_URLMAXSIZE) && ((int) strlen(lien)<HTS_URLMAXSIZE)) {

      /* patch scheme if necessary */
      if (strfield(lien,"http:")) {
        lien+=5;
        strcpybuff(adr, jump_protocol(origin_adr));    // même adresse ; protocole vide (http)
      } else if (strfield(lien,"https:")) {
        lien+=6;
        strcpybuff(adr, "https://");   // même adresse forcée en https
        strcatbuff(adr, jump_protocol(origin_adr));
      } else if (strfield(lien,"ftp:")) {
        lien+=4;
        strcpybuff(adr, "ftp://");   // même adresse forcée en ftp
        strcatbuff(adr, jump_protocol(origin_adr));
#if HTS_USEMMS
      } else if (strfield(lien,"mms:")) {
        lien+=4;
        strcpybuff(adr, "mms://");   // même adresse forcée en ftp
        strcatbuff(adr, jump_protocol(origin_adr));
#endif
      } else {
        strcpybuff(adr,origin_adr);    // même adresse ; et même éventuel protocole
      }
      
      if (*lien!='/') {  // sinon c'est un lien absolu
        if (*lien == '\0') {
          strcpybuff(fil,origin_fil);
        } else if (*lien == '?') {     // example: a href="?page=2"
          char* a;
          strcpybuff(fil,origin_fil);
          a=strchr(fil,'?');
          if (a) *a='\0';
          strcatbuff(fil,lien);
        } else {
          const char *a=strchr(origin_fil,'?');
          if (a == NULL) a=origin_fil+strlen(origin_fil);
          while((*a!='/') && ( a > origin_fil) ) a--;
          if (*a=='/') {    // ok on a un '/'
            if ( (((int) (a - origin_fil))+1+strlen(lien)) < HTS_URLMAXSIZE) {
              // copier chemin
              strncpy(fil,origin_fil,((int) (a - origin_fil))+1);
              *(fil + ((int) (a - origin_fil))+1)='\0';
              
              // copier chemin relatif
              if (((int) strlen(fil)+(int) strlen(lien)) < HTS_URLMAXSIZE) {
                strcatbuff(fil,lien + ((*lien=='/')?1:0) );      
                // simplifier url pour les ../
                fil_simplifie(fil);
              } else
                ok=-1;    // erreur
            } else {    // erreur
              ok=-1;    // erreur URL
            }
          } else {    // erreur
            ok=-1;    // erreur URL
          }
        }
      } else { // chemin absolu
        // copier chemin directement
        strcatbuff(fil,lien);      
        fil_simplifie(fil);
      }  // *lien!='/'
    } else
      ok=-1;
    
  }  // test news: etc.

  // case insensitive pour adresse
  {
    char *a=jump_identification(adr);
    while(*a) {
      if ((*a>='A') && (*a<='Z'))
        *a+='a'-'A';       
      a++;
    }
  }
  
  return ok;
}
Exemple #6
0
// GESTION DES TABLES DE HACHAGE
// Méthode à 2 clés (adr+fil), 2e cle facultative
// hash[no_enregistrement][pos]->hash est un index dans le tableau général liens
// #define HTS_HASH_SIZE 8191  (premier si possible!)
// type: numero enregistrement - 0 est case insensitive (sav) 1 (adr+fil) 2 (former_adr+former_fil)
// recherche dans la table selon nom1,nom2 et le no d'enregistrement
// retour: position ou -1 si non trouvé
int hash_read(const hash_struct* hash,char* nom1,char* nom2,int type,int normalized) {
  char BIGSTK normfil_[HTS_URLMAXSIZE*2];
	char catbuff[CATBUFF_SIZE];
  char* normfil;
  char* normadr;
  unsigned int cle;
  int pos; 
  // calculer la clé de recherche, non modulée
  if (type)
    cle = hash_cle(nom1,nom2);
  else
    cle = hash_cle(convtolower(catbuff,nom1),nom2);         // case insensitive
  // la position se calcule en modulant
  pos = (int) (cle%HTS_HASH_SIZE);
  // entrée trouvée?
  if (hash->hash[type][pos] >= 0) {             // un ou plusieurs enregistrement(s) avec une telle clé existe..
    // tester table de raccourcis (hash)
    // pos est maintenant la position recherchée dans liens
    pos = hash->hash[type][pos];
    while (pos>=0) {              // parcourir la chaine
      switch (type) {
      case 0:         // sav
        if (strfield2(nom1,hash->liens[pos]->sav)) {  // case insensitive
#if DEBUG_HASH==2
          printf("hash: found shortcut at %d\n",pos);
#endif
          return pos;
        }
        break;
      case 1:         // adr+fil
        {
          if (!normalized)
            normfil=hash->liens[pos]->fil;
          else
            normfil=fil_normalized(hash->liens[pos]->fil,normfil_);
          if (!normalized)
            normadr = jump_identification(hash->liens[pos]->adr);
          else
            normadr = jump_normalized(hash->liens[pos]->adr);
          if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) {
#if DEBUG_HASH==2
            printf("hash: found shortcut at %d\n",pos);
#endif
            return pos;
          }
        }
        break;
      case 2:         // former_adr+former_fil
        {
          if (hash->liens[pos]->former_adr) {
            if (!normalized)
              normfil=hash->liens[pos]->former_fil;
            else
              normfil=fil_normalized(hash->liens[pos]->former_fil,normfil_);
            if (!normalized)
              normadr = jump_identification(hash->liens[pos]->former_adr);
            else
              normadr = jump_normalized(hash->liens[pos]->former_adr);
            
            if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) {
#if DEBUG_HASH==2
              printf("hash: found shortcut at %d\n",pos);
#endif
              return pos;
            }
          }
        }
        break;
      }
      // calculer prochaine position dans la chaine
      {
        int old=pos;
        pos=hash->liens[pos]->hash_next[type];   // sinon prochain dans la chaine
        if (old==pos)
          pos=-1;         // erreur de bouclage (ne devrait pas arriver)
      }
    }
    
    // Ok va falloir chercher alors..
    /*pos=hash->max_lien;    // commencer à max_lien
    switch (type) {
    case 0:         // sav
      while(pos>=0) {
        if (hash->liens[pos]->hash_sav == cle ) {
          if (strcmp(nom1,hash->liens[pos]->sav)==0) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
      break;
    case 1:         // adr+fil
      while(pos>=0) {
        if (hash->liens[pos]->hash_adrfil == cle ) {
          if ((strcmp(nom1,hash->liens[pos]->adr)==0) && (strcmp(nom2,hash->liens[pos]->fil)==0)) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
      break;
    case 2:         // former_adr+former_fil
      while(pos>=0) {
        if (hash->liens[pos]->hash_fadrfil == cle ) {
          if (hash->liens[pos]->former_adr)
            if ((strcmp(nom1,hash->liens[pos]->former_adr)==0) && (strcmp(nom2,hash->liens[pos]->former_fil)==0)) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
    }*/
#if DEBUG_HASH==1
    printf("hash: not found after test %s%s\n",nom1,nom2);
#endif
    return -1;    // non trouvé
  } else {
#if DEBUG_HASH==2
    printf("hash: not found %s%s\n",nom1,nom2);
#endif
    return -1;    // non trouvé : clé non entrée (même une fois)
  }
}
Exemple #7
0
// enregistrement lien lpos dans les 3 tables hash1..3
void hash_write(hash_struct* hash,int lpos,int normalized) {
  char BIGSTK normfil_[HTS_URLMAXSIZE*2];
	char catbuff[CATBUFF_SIZE];
  char* normfil;
  unsigned int cle;
  int pos; 
  int* ptr;
  //
  if (hash->liens[lpos]) {                       // on sait jamais..
    hash->max_lien = max(hash->max_lien,lpos);
#if DEBUG_HASH
    hashnumber=hash->max_lien;
#endif
    // élément actuel sur -1 (fin de chaine)
    hash->liens[lpos]->hash_next[0]=hash->liens[lpos]->hash_next[1]=hash->liens[lpos]->hash_next[2]=-1;
    //
    cle = hash_cle(convtolower(catbuff,hash->liens[lpos]->sav),"");    // CASE INSENSITIVE
    pos = (int) (cle%HTS_HASH_SIZE);
    ptr = hash_calc_chaine(hash,0,pos);         // calculer adresse chaine
    *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
    printf("[%d",pos);
#endif
    //
    if (!normalized)
      normfil=hash->liens[lpos]->fil;
    else
      normfil=fil_normalized(hash->liens[lpos]->fil,normfil_);
    if (!normalized)
      cle = hash_cle(jump_identification(hash->liens[lpos]->adr),normfil);
    else
      cle = hash_cle(jump_normalized(hash->liens[lpos]->adr),normfil);
    pos = (int) (cle%HTS_HASH_SIZE);
    ptr = hash_calc_chaine(hash,1,pos);         // calculer adresse chaine
    *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
    printf(",%d",pos);
#endif
    //
    if (hash->liens[lpos]->former_adr) {         // former_adr existe?
      if (!normalized)
        normfil=hash->liens[lpos]->former_fil;
      else
        normfil=fil_normalized(hash->liens[lpos]->former_fil,normfil_);
      if (!normalized)
        cle = hash_cle(jump_identification(hash->liens[lpos]->former_adr),normfil);
      else
        cle = hash_cle(jump_normalized(hash->liens[lpos]->former_adr),normfil);
      pos = (int) (cle%HTS_HASH_SIZE);
      ptr = hash_calc_chaine(hash,2,pos);         // calculer adresse chaine
      *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
      printf(",%d",pos);
#endif
    }
#if DEBUG_HASH==3
    printf("] "); fflush(stdout);
#endif
  }
#if DEBUT_HASH
  else {
    printf("* hash_write=0!!\n");
    abortLogFmt("unexpected error in hash_write (pos=%d)" _ pos);
    exit(1);
  }
#endif
  //
}
Exemple #8
0
Fichier : htshelp.c Projet : ahua/c
void help_wizard(httrackp* opt) {
  char* urls = (char*) malloct(HTS_URLMAXSIZE*2);
  char* mainpath = (char*) malloct(256);
  char* projname = (char*) malloct(256);
  char* stropt = (char*) malloct(2048);     // options
  char* stropt2 = (char*) malloct(2048);    // options longues
  char* strwild = (char*) malloct(2048);    // wildcards
  char* cmd = (char*) malloct(4096);
  char* str = (char*) malloct(256);
  char** argv = (char**) malloct(256 * sizeof(char*));
  //
  char* a;
  //
  if (urls == NULL || mainpath == NULL || projname == NULL || stropt == NULL 
    || stropt2 == NULL || strwild == NULL || cmd == NULL || str == NULL || argv == NULL) {
    fprintf(stderr, "* memory exhausted in %s, line %d\n", __FILE__, __LINE__);
    return;
  }
  urls[0] = mainpath[0] = projname[0] = stropt[0] = stropt2[0] = strwild[0] = cmd[0] = str[0] = '\0';
  //
  strcpybuff(stropt,"-");
  mainpath[0]=projname[0]=stropt2[0]=strwild[0]='\0';
  //
  
  printf("\n");
  printf("Welcome to HTTrack Website Copier (Offline Browser) "HTTRACK_VERSION"%s\n", hts_get_version_info(opt));
  printf("Copyright (C) Xavier Roche and other contributors\n");
#ifdef _WIN32
  printf("Note: You are running the commandline version,\n");
  printf("run 'WinHTTrack.exe' to get the GUI version.\n");
#endif
#ifdef HTTRACK_AFF_WARNING
  printf("NOTE: "HTTRACK_AFF_WARNING"\n");
#endif
#ifdef HTS_PLATFORM_NAME
#if USE_BEGINTHREAD
  printf("[compiled: "HTS_PLATFORM_NAME" - MT]\n");
#else
  printf("[compiled: "HTS_PLATFORM_NAME"]\n");
#endif
#endif
  printf("To see the option list, enter a blank line or try httrack --help\n");
  //
  // Project name
  while(strnotempty(projname)==0) {
    printf("\n");
    printf("Enter project name :");
    fflush(stdout);
    linput(stdin,projname,250);
    if (strnotempty(projname)==0)
      help("httrack",1);
  }
  //
  // Path
  if (strnotempty(hts_gethome()))
    printf("\nBase path (return=%s/websites/) :",hts_gethome());
  else
    printf("\nBase path (return=current directory) :");
  linput(stdin,str,250);
  if (!strnotempty(str)) {
    strcatbuff(str,hts_gethome());
    strcatbuff(str,"/websites/");
  }
  if (strnotempty(str))
  if ((str[strlen(str)-1]!='/') && (str[strlen(str)-1]!='\\'))
    strcatbuff(str,"/");
  strcatbuff(stropt2,"-O \""); strcatbuff(stropt2,str); strcatbuff(stropt2,projname); strcatbuff(stropt2,"\" ");
  // Créer si ce n'est fait un index.html 1er niveau
  make_empty_index(str);
  //
  printf("\n");
  printf("Enter URLs (separated by commas or blank spaces) :");
  fflush(stdout);
  linput(stdin,urls,250);
  if (strnotempty(urls)) {
    while( (a=strchr(urls,',')) )  *a=' ';
    while( (a=strchr(urls,'\t')) ) *a=' ';
    
    // Action
    printf("\nAction:\n");
    switch(help_query("Mirror Web Site(s)|Mirror Web Site(s) with Wizard|Just Get Files Indicated|Mirror ALL links in URLs (Multiple Mirror)|Test Links In URLs (Bookmark Test)|Update/Continue a Mirror",1)) {
    case 1: break; 
    case 2: strcatbuff(stropt,"W"); break;
    case 3: strcatbuff(stropt2,"--get "); break;
    case 4: strcatbuff(stropt2,"--mirrorlinks "); break;
    case 5: strcatbuff(stropt2,"--testlinks "); break;
    case 6: strcatbuff(stropt2,"--update "); break;
    case 0: return; break;
    }
      
    // Proxy
    printf("\nProxy (return=none) :");
    linput(stdin,str,250);
    if (strnotempty(str)) {
      while( (a=strchr(str,' ')) ) *a=':';    // port
      if (!strchr(jump_identification(str),':')) {
        char str2[256];
        printf("\nProxy port (return=8080) :");
        linput(stdin,str2,250);
        strcatbuff(str,":");
        if (strnotempty(str2)==0)
          strcatbuff(str,"8080");
        else
          strcatbuff(str,str2);
      }
      strcatbuff(stropt2,"-P "); strcatbuff(stropt2,str); strcatbuff(stropt2," ");
    }
    
    // Display
    strcatbuff(stropt2," -%v ");

    // Wildcards
    printf("\nYou can define wildcards, like: -*.gif +www.*.com/*.zip -*img_*.zip\n");
    printf("Wildcards (return=none) :");
    linput(stdin,strwild,250);
    
    // Options
    do {
      printf("\nYou can define additional options, such as recurse level (-r<number>), separed by blank spaces\n");
      printf("To see the option list, type help\n");
      printf("Additional options (return=none) :");
      linput(stdin,str,250);
      if (strfield2(str,"help")) {
        help("httrack",2);
      } else if (strnotempty(str)) {
        strcatbuff(stropt2,str);
        strcatbuff(stropt2," ");
      }
    } while(strfield2(str,"help"));
    
    {
      int argc=1;
      int g=0;
      int i=0;
      //
      printf("\n");
      if (strlen(stropt)==1)
        stropt[0]='\0';    // aucune
      sprintf(cmd,"%s %s %s %s",urls,stropt,stropt2,strwild);
      printf("---> Wizard command line: httrack %s\n\n",cmd);
      printf("Ready to launch the mirror? (Y/n) :");
      fflush(stdout);
      linput(stdin,str,250);
      if (strnotempty(str)) {
        if (!((str[0]=='y') || (str[0]=='Y')))
          return ;
      }
      printf("\n");

      // couper en morceaux
      argv[0]="winhttrack";
      argv[1]=cmd;
      argc++;    
      while(cmd[i])  {
        if(cmd[i]=='\"') g=!g;
        if(cmd[i]==' '){
          if(!g){
            cmd[i]='\0';
            argv[argc++]=cmd+i+1;
          }
        }  
        i++;
      }
      hts_main(argc,argv);
    }
  //} else {
  //  help("httrack",1);
  }

  /* Free buffers */
  freet(urls);
  freet(mainpath);
  freet(projname);
  freet(stropt);
  freet(stropt2);
  freet(strwild);
  freet(cmd);
  freet(str);
}
Exemple #9
0
// la véritable fonction une fois lancées les routines thread/fork
int run_launch_ftp(FTPDownloadStruct * pStruct) {
  lien_back *back = pStruct->pBack;
  httrackp *opt = pStruct->pOpt;
  char user[256] = "anonymous";
  char pass[256] = "user@";
  char line_retr[2048];
  int port = 21;

#if FTP_PASV
  int port_pasv = 0;
#endif
  char BIGSTK adr_ip[1024];
  char *adr, *real_adr;
  char *ftp_filename = "";
  int timeout = 300;            // timeout
  int timeout_onfly = 8;        // attente réponse supplémentaire
  int transfer_list = 0;        // directory
  int rest_understood = 0;      // rest command understood
  t_fullhostent fullhostent_buffer;     // buffer pour resolver

  //
  T_SOC soc_ctl = INVALID_SOCKET;
  T_SOC soc_servdat = INVALID_SOCKET;
  T_SOC soc_dat = INVALID_SOCKET;

  //
  SOCaddr server_data;
  int server_data_size = sizeof(server_data);

  //
  line_retr[0] = adr_ip[0] = '\0';

  timeout = 300;

  // effacer
  strcpybuff(back->r.msg, "");
  back->r.statuscode = 0;
  back->r.size = 0;

  // récupérer user et pass si présents, et sauter user:id@ dans adr
  real_adr = strchr(back->url_adr, ':');
  if (real_adr)
    real_adr++;
  else
    real_adr = back->url_adr;
  while(*real_adr == '/')
    real_adr++;                 // sauter /
  if ((adr = jump_identification(real_adr)) != real_adr) {      // user
    int i = -1;

    pass[0] = '\0';
    do {
      i++;
      user[i] = real_adr[i];
    } while((real_adr[i] != ':') && (real_adr[i]));
    user[i] = '\0';
    if (real_adr[i] == ':') {   // pass
      int j = -1;

      i++;                      // oui on saute aussi le :
      do {
        j++;
        pass[j] = real_adr[i + j];
      } while(((&real_adr[i + j + 1]) < adr) && (real_adr[i + j]));
      pass[j] = '\0';
    }
  }
  // Calculer RETR <nom>
  {
    char *a;

#if 0
    a = back->url_fil + strlen(back->url_fil) - 1;
    while((a > back->url_fil) && (*a != '/'))
      a--;
    if (*a != '/') {
      a = NULL;
    }
#else
    a = back->url_fil;
#endif
    if (a != NULL && *a != '\0') {
#if 0
      a++;                      // sauter /
#endif
      ftp_filename = a;
      if (strnotempty(a)) {
        char catbuff[CATBUFF_SIZE];
        char *ua = unescape_http(catbuff, a);
        int len_a = (int) strlen(ua);

        if (len_a > 0 && ua[len_a - 1] == '/') {        /* obviously a directory listing */
          transfer_list = 1;
          snprintf(line_retr, sizeof(line_retr), "LIST -A %s", ua);
        } else if ((strchr(ua, ' '))
                   || (strchr(ua, '\"'))
                   || (strchr(ua, '\''))
          ) {
          snprintf(line_retr, sizeof(line_retr), "RETR \"%s\"", ua);
        } else {                /* Regular one */
          snprintf(line_retr, sizeof(line_retr), "RETR %s", ua);
        }
      } else {
        transfer_list = 1;
        snprintf(line_retr, sizeof(line_retr), "LIST -A");
      }
    } else {
      strcpybuff(back->r.msg, "Unexpected PORT error");
      // back->status=STATUS_FTP_READY;    // fini
      back->r.statuscode = STATUSCODE_INVALID;
    }
  }

#if FTP_DEBUG
  printf("Connecting to %s...\n", adr);
#endif

  // connexion
  {
    SOCaddr server;
    int server_size = sizeof(server);
    t_hostent *hp;
    char *a;
    char _adr[256];
    const char *error = "unknown error";

    _adr[0] = '\0';
    //T_SOC soc_ctl;
    // effacer structure
    memset(&server, 0, sizeof(server));

    // port
    a = strchr(adr, ':');       // port
    if (a) {
      sscanf(a + 1, "%d", &port);
      strncatbuff(_adr, adr, (int) (a - adr));
    } else
      strcpybuff(_adr, adr);

    // récupérer adresse résolue
    strcpybuff(back->info, "host name");
    hp = hts_gethostbyname2(opt, _adr, &fullhostent_buffer, &error);
    if (hp == NULL) {
      snprintf(back->r.msg, sizeof(back->r.msg),
               "Unable to get server's address: %s", error);
      // back->status=STATUS_FTP_READY;    // fini
      back->r.statuscode = STATUSCODE_NON_FATAL;
      _HALT_FTP return 0;
    }
    _CHECK_HALT_FTP;

    // copie adresse
    SOCaddr_copyaddr(server, server_size, hp->h_addr_list[0], hp->h_length);
    // copie adresse pour cnx data
    SOCaddr_copyaddr(server_data, server_data_size, hp->h_addr_list[0],
                     hp->h_length);
    // memcpy(&server.sin_addr, hp->h_addr, hp->h_length);

    // créer ("attachement") une socket (point d'accès) internet,en flot
    soc_ctl = (T_SOC) socket(SOCaddr_sinfamily(server), SOCK_STREAM, 0);
    if (soc_ctl == INVALID_SOCKET) {
      strcpybuff(back->r.msg, "Unable to create a socket");
      // back->status=STATUS_FTP_READY;    // fini
      back->r.statuscode = STATUSCODE_INVALID;
      _HALT_FTP return 0;
    }
Exemple #10
0
// tester taille
int hts_testlinksize(httrackp* opt,
                     char* adr,char* fil,
                     LLint size) {
  int jok=0;
  if (size>=0) {
    char BIGSTK l[HTS_URLMAXSIZE*2];
    char BIGSTK lfull[HTS_URLMAXSIZE*2];
    if (size>=0) {
      LLint sz=size;
      int size_flag=0;
      
      // former URL complète du lien actuel
      strcpybuff(l,jump_identification(adr));
      if (*fil!='/') strcatbuff(l,"/");
      strcatbuff(l,fil);
      //
      if (!link_has_authority(adr))
        strcpybuff(lfull,"http://");
      else
        lfull[0]='\0';
      strcatbuff(lfull,adr);
      if (*fil!='/') strcatbuff(l,"/");
      strcatbuff(lfull,fil);
      
      // filters, 0=sait pas 1=ok -1=interdit
      {
        int jokDepth1=0,jokDepth2=0;
        int jok1=0,jok2=0;
        LLint sz1=size,sz2=size;
        int size_flag1=0,size_flag2=0;
        jok1  = fa_strjoker(/*url*/0, *opt->filters.filters,*opt->filters.filptr,lfull,&sz1,&size_flag1,&jokDepth1);
        jok2 =  fa_strjoker(/*url*/0, *opt->filters.filters,*opt->filters.filptr,l,    &sz2,&size_flag2,&jokDepth2);
        if (jok2 == 0) {      // #2 doesn't know
          jok = jok1;        // then, use #1
          sz = sz1;
          size_flag = size_flag1;
        } else if (jok1 == 0) {  // #1 doesn't know
          jok = jok2;        // then, use #2
          sz = sz2;
          size_flag = size_flag2;
        } else if (jokDepth1 >= jokDepth2) { // #1 matching rule is "after" #2, then it is prioritary
          jok = jok1;
          sz = sz1;
          size_flag = size_flag1;
        } else {                              // #2 matching rule is "after" #1, then it is prioritary
          jok = jok2;
          sz = sz2;
          size_flag = size_flag2;
        } 
      }
      

      // log
      if (jok==1) {
        if ((opt->debug>1) && (opt->log!=NULL)) {
          HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"File confirmed (size test): %s%s ("LLintP")"LF,adr,fil,(LLint)(size));
        }
      } else if (jok==-1) {
        if (size_flag) {        /* interdit à cause de la taille */
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"File cancelled due to its size: %s%s ("LLintP", limit: "LLintP")"LF,adr,fil,(LLint)(size),(LLint)(sz));
          }
        } else {
          jok=1;
        }
      }
    }
  }
  return jok;
}
Exemple #11
0
static int hts_acceptlink_(httrackp* opt,
													int ptr,int lien_tot,lien_url** liens,
													char* adr,char* fil,
													char* tag, char* attribute,
													int* set_prio_to,
													int* just_test_it) 
{
  int forbidden_url=-1;
  int meme_adresse;
	int embedded_triggered = 0;
#define _FILTERS     (*opt->filters.filters)
#define _FILTERS_PTR (opt->filters.filptr)
#define _ROBOTS      ((robots_wizard*)opt->robotsptr)
  int may_set_prio_to=0;

  // -------------------- PHASE 0 --------------------

  /* Infos */
  if ((opt->debug>1) && (opt->log!=NULL)) {
    HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"wizard test begins: %s%s"LF,adr,fil);
    test_flush;
  }
  
  /* Already exists? Then, we know that we knew that this link had to be known */
  if (adr[0] != '\0'
    && fil[0] != '\0'
    && opt->hash != NULL
    && hash_read(opt->hash, adr, fil, 1, opt->urlhack) >= 0
    ) {
    return 0;  /* Yokai */
  }
  
  // -------------------- PRELUDE OF PHASE 3-BIS --------------------

	/* Built-in known tags (<img src=..>, ..) */
	if (forbidden_url != 0 && opt->nearlink && tag != NULL && attribute != NULL) {
		int i;
		for(i = 0 ; hts_detect_embed[i].tag != NULL ; i++) {
			if (cmp_token(tag, hts_detect_embed[i].tag)
				&& cmp_token(attribute, hts_detect_embed[i].attr)
				) 
			{
				embedded_triggered = 1;
				break;
			}
		}
	}


  // -------------------- PHASE 1 --------------------

  /* Doit-on traiter les non html? */
  if ((opt->getmode & 2)==0) {    // non on ne doit pas
    if (!ishtml(opt,fil)) {  // non il ne faut pas
      //adr[0]='\0';    // ne pas traiter ce lien, pas traiter
      forbidden_url=1;    // interdire récupération du lien
      if ((opt->debug>1) && (opt->log!=NULL)) {
        HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"non-html file ignored at %s : %s"LF,adr,fil);
        test_flush;
      }
      
    }
  }
  
  /* Niveau 1: ne pas parser suivant! */
  if (ptr>0) {
    if ( ( liens[ptr]->depth <= 0 ) || ( liens[ptr]->depth <= 1 && !embedded_triggered ) ) {
      forbidden_url=1;    // interdire récupération du lien
      if ((opt->debug>1) && (opt->log!=NULL)) {
        HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"file from too far level ignored at %s : %s"LF,adr,fil);
        test_flush;
      }
    }
  }

  /* en cas d'échec en phase 1, retour immédiat! */
  if (forbidden_url == 1) {
    return forbidden_url;
  }
  
  // -------------------- PHASE 2 --------------------

  // ------------------------------------------------------
  // doit-on traiter ce lien?.. vérifier droits de déplacement
  meme_adresse=strfield2(adr,urladr);
  if ((opt->debug>1) && (opt->log!=NULL)) {
    HTS_LOG(opt,LOG_DEBUG); 
    if (meme_adresse) 
      fprintf(opt->log,"Compare addresses: %s=%s"LF,adr,urladr);
    else
      fprintf(opt->log,"Compare addresses: %s!=%s"LF,adr,urladr);
    test_flush;
  }
  if (meme_adresse) {  // même adresse 
    {  // tester interdiction de descendre
      // MODIFIE : en cas de remontée puis de redescente, il se pouvait qu'on ne puisse pas atteindre certains fichiers
      // problème: si un fichier est virtuellement accessible via une page mais dont le lien est sur une autre *uniquement*..
      char BIGSTK tempo[HTS_URLMAXSIZE*2];
      char BIGSTK tempo2[HTS_URLMAXSIZE*2];
      tempo[0] = tempo2[0] = '\0';
      
      // note (up/down): on calcule à partir du lien primaire, ET du lien précédent.
      // ex: si on descend 2 fois on peut remonter 1 fois
      
      if (lienrelatif(tempo,fil,liens[liens[ptr]->premier]->fil)==0) {
        if (lienrelatif(tempo2,fil,liens[ptr]->fil)==0) {
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"build relative links to test: %s %s (with %s and %s)"LF,tempo,tempo2,liens[liens[ptr]->premier]->fil,liens[ptr]->fil);
            test_flush;
          }
          
          // si vient de primary, ne pas tester lienrelatif avec (car host "différent")
          /*if (liens[liens[ptr]->premier] == 0) {   // vient de primary
          }
          */
          
          // NEW: finalement OK, sauf pour les moved repérés par link_import
          // PROBLEME : annulé a cause d'un lien éventuel isolé accepté..qui entrainerait un miroir
          
          // (test même niveau (NOUVEAU à cause de certains problèmes de filtres non intégrés))
          // NEW
          if ( 
            (tempo[0]  != '\0' && tempo[1]  != '\0' && strchr(tempo+1,'/') == 0)
            ||
            (tempo2[0] != '\0' && tempo2[1] != '\0' && strchr(tempo2+1,'/') == 0) 
            ) {
            if (!liens[ptr]->link_import) {   // ne résulte pas d'un 'moved'
              forbidden_url=0;
              if ((opt->debug>1) && (opt->log!=NULL)) {
                HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"same level link authorized: %s%s"LF,adr,fil);
                test_flush;
             }
            }
          }
          
          // down
          if ( (strncmp(tempo,"../",3)) || (strncmp(tempo2,"../",3)))  {   // pas montée sinon ne nbous concerne pas
            int test1,test2;
            if (!strncmp(tempo,"../",3))
              test1=0;
            else
              test1 = (strchr(tempo +((*tempo =='/')?1:0),'/')!=NULL);
            if (!strncmp(tempo2,"../",3))
              test2=0;
            else
              test2 = (strchr(tempo2+((*tempo2=='/')?1:0),'/')!=NULL);
            if ( (test1) && (test2) ) {   // on ne peut que descendre
              if ((opt->seeker & 1)==0) {  // interdiction de descendre
                forbidden_url=1;
                if ((opt->debug>1) && (opt->log!=NULL)) {
                  HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"lower link canceled: %s%s"LF,adr,fil);
                  test_flush;
                }
              } else {    // autorisé à priori - NEW
                if (!liens[ptr]->link_import) {   // ne résulte pas d'un 'moved'
                  forbidden_url=0;
                  if ((opt->debug>1) && (opt->log!=NULL)) {
                    HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"lower link authorized: %s%s"LF,adr,fil);
                    test_flush;
                  }
                }
              }
            } else if ( (test1) || (test2) ) {   // on peut descendre pour accéder au lien
              if ((opt->seeker & 1)!=0) {  // on peut descendre - NEW
                if (!liens[ptr]->link_import) {   // ne résulte pas d'un 'moved'
                  forbidden_url=0;
                  if ((opt->debug>1) && (opt->log!=NULL)) {
                    HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"lower link authorized: %s%s"LF,adr,fil);
                    test_flush;
                  }
                }
              }
            }
          }
          
          
          // up
          if ( (!strncmp(tempo,"../",3)) && (!strncmp(tempo2,"../",3)) ) {    // impossible sans monter
            if ((opt->seeker & 2)==0) {  // interdiction de monter
              forbidden_url=1;
              if ((opt->debug>1) && (opt->log!=NULL)) {
                HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"upper link canceled: %s%s"LF,adr,fil);
                test_flush;
              }
            } else {       // autorisé à monter - NEW
              if (!liens[ptr]->link_import) {   // ne résulte pas d'un 'moved'
                forbidden_url=0;
                if ((opt->debug>1) && (opt->log!=NULL)) {
                  HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"upper link authorized: %s%s"LF,adr,fil);
                  test_flush;
                }
              }
            }
          } else if ( (!strncmp(tempo,"../",3)) || (!strncmp(tempo2,"../",3)) ) {    // Possible en montant
            if ((opt->seeker & 2)!=0) {  // autorisé à monter - NEW
              if (!liens[ptr]->link_import) {   // ne résulte pas d'un 'moved'
                forbidden_url=0;
                if ((opt->debug>1) && (opt->log!=NULL)) {
                  HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"upper link authorized: %s%s"LF,adr,fil);
                  test_flush;
                }
              }
            }  // sinon autorisé en descente
          }
          
          
        } else {
          if (opt->log) {
            fprintf(opt->log,"Error building relative link %s and %s"LF,fil,liens[ptr]->fil);
            test_flush;
          }
        }
      } else {
        if (opt->log) {
          fprintf(opt->log,"Error building relative link %s and %s"LF,fil,liens[liens[ptr]->premier]->fil);
          test_flush;
        }
      }
      
    }  // tester interdiction de descendre?
    
    {  // tester interdiction de monter
      char BIGSTK tempo[HTS_URLMAXSIZE*2];
      char BIGSTK tempo2[HTS_URLMAXSIZE*2];
      if (lienrelatif(tempo,fil,liens[liens[ptr]->premier]->fil)==0) {
        if (lienrelatif(tempo2,fil,liens[ptr]->fil)==0) {
        } else {
          if (opt->log) { 
            fprintf(opt->log,"Error building relative link %s and %s"LF,fil,liens[ptr]->fil);
            test_flush;
          }
          
        }
      } else {
        if (opt->log) { 
          fprintf(opt->log,"Error building relative link %s and %s"LF,fil,liens[liens[ptr]->premier]->fil);
          test_flush;
        }
        
      }
    }   // fin tester interdiction de monter
    
  } else {    // adresse différente, sortir?
    
    //if (!opt->wizard) {    // mode non wizard
    // doit-on traiter ce lien?.. vérifier droits de sortie
    switch((opt->travel & 255)) {
    case 0: 
      if (!opt->wizard)    // mode non wizard
        forbidden_url=1; break;    // interdicton de sortir au dela de l'adresse
    case 1: {              // sortie sur le même dom.xxx
      size_t i = strlen(adr)-1;
      size_t j = strlen(urladr)-1;
      while( (i>0) && (adr[i]!='.')) i--;
      while( (j>0) && (urladr[j]!='.')) j--;
      i--; j--;
      while( (i>0) && (adr[i]!='.')) i--;
      while( (j>0) && (urladr[j]!='.')) j--;
      if ((i>0) && (j>0)) {
        if (!strfield2(adr+i,urladr+j)) {   // !=
          if (!opt->wizard) {   // mode non wizard
            //printf("refused: %s\n",adr);
            forbidden_url=1;  // pas même domaine  
            if ((opt->debug>1) && (opt->log!=NULL)) {
              HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"foreign domain link canceled: %s%s"LF,adr,fil);
              test_flush;
            }
          }
          
        } else {
          if (opt->wizard) {   // mode wizard
            forbidden_url=0;  // même domaine  
            if ((opt->debug>1) && (opt->log!=NULL)) {
              HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"same domain link authorized: %s%s"LF,adr,fil);
              test_flush;
            }
          }
        }
        
      } else
        forbidden_url=1;
            } 
      break;  
    case 2: {                      // sortie sur le même .xxx
      size_t i = strlen(adr)-1;
      size_t j = strlen(urladr)-1;
      while( (i>0) && (adr[i]!='.')) i--;
      while( (j>0) && (urladr[j]!='.')) j--;
      if ((i>0) && (j>0)) {
        if (!strfield2(adr+i,urladr+j)) {   // !-
          if (!opt->wizard) {   // mode non wizard
            //printf("refused: %s\n",adr);
            forbidden_url=1;  // pas même .xx  
            if ((opt->debug>1) && (opt->log!=NULL)) {
              HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"foreign location link canceled: %s%s"LF,adr,fil);
              test_flush;
            }
          }
        } else {
          if (opt->wizard) {   // mode wizard
            forbidden_url=0;  // même domaine  
            if ((opt->debug>1) && (opt->log!=NULL)) {
              HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"same location link authorized: %s%s"LF,adr,fil);
              test_flush;
            }
          }
        }
      } else forbidden_url=1;     
            } 
      break;
    case 7:                 // everywhere!!
      if (opt->wizard) {   // mode wizard
        forbidden_url=0;
        break;
      }
    }  // switch
    
    // ANCIENNE POS -- récupérer les liens à côtés d'un lien (nearlink)
    
  }  // fin test adresse identique/différente

  // -------------------- PHASE 3 --------------------

  // récupérer les liens à côtés d'un lien (nearlink) (nvelle pos)
  if (forbidden_url != 0 && opt->nearlink) {
    if (!ishtml(opt,fil)) {  // non html
      //printf("ok %s%s\n",ad,fil);
      forbidden_url=0;    // autoriser
      may_set_prio_to=1+1; // set prio to 1 (parse but skip urls) if near is the winner
      if ((opt->debug>1) && (opt->log!=NULL)) {
        HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"near link authorized: %s%s"LF,adr,fil);
        test_flush;
      }
    }
  }

  // -------------------- PHASE 3-BIS --------------------

	/* Built-in known tags (<img src=..>, ..) */
	if (forbidden_url != 0 && embedded_triggered) {
		forbidden_url=0;    // autoriser
		may_set_prio_to=1+1; // set prio to 1 (parse but skip urls) if near is the winner
		if ((opt->debug>1) && (opt->log!=NULL)) {
			HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"near link authorized (friendly tag): %s%s"LF,adr,fil);
			test_flush;
		}
	}


  // -------------------- PHASE 4 --------------------
  
  // ------------------------------------------------------
  // Si wizard, il se peut qu'on autorise ou qu'on interdise 
  // un lien spécial avant même de tester sa position, sa hiérarchie etc.
  // peut court-circuiter le forbidden_url précédent
  if (opt->wizard) { // le wizard entre en action..
    //
    int question=1;         // poser une question                            
    int force_mirror=0;     // pour mirror links
    int filters_answer=0;   // décision prise par les filtres
    char BIGSTK l[HTS_URLMAXSIZE*2];
    char BIGSTK lfull[HTS_URLMAXSIZE*2];
    
    if (forbidden_url!=-1) question=0;  // pas de question, résolu
    
    // former URL complète du lien actuel
    strcpybuff(l,jump_identification(adr));
    if (*fil!='/') strcatbuff(l,"/");
    strcatbuff(l,fil);
    // full version (http://foo:[email protected]/bar.html)
    if (!link_has_authority(adr))
      strcpybuff(lfull,"http://");
    else
      lfull[0]='\0';
    strcatbuff(lfull,adr);
    if (*fil!='/') strcatbuff(lfull,"/");
    strcatbuff(lfull,fil);
    
    // tester filters (URLs autorisées ou interdites explicitement)
    
    // si lien primaire on saute le joker, on est pas lémur
    if (ptr==0) {  // lien primaire, autoriser
      question=1;    // la question sera résolue automatiquement
      forbidden_url=0;
      may_set_prio_to=0;    // clear may-set flag
    } else {
      // eternal depth first
      // vérifier récursivité extérieure
      if (opt->extdepth>0) {
        if ( /*question && */ (ptr>0) && (!force_mirror)) {
          // well, this is kinda a hak
          // we don't want to mirror EVERYTHING, and we have to decide where to stop
          // there is no way yet to tag "external" links, and therefore links that are
          // "weak" (authorized depth < external depth) are just not considered for external
          // hack
          if (liens[ptr]->depth > opt->extdepth) {
            // *set_prio_to = opt->extdepth + 1;
            *set_prio_to = 1 + (opt->extdepth);
            may_set_prio_to=0;  // clear may-set flag
            forbidden_url=0;    // autorisé
            question=0;         // résolution auto
            if ((opt->debug>1) && (opt->log!=NULL)) {
              if (question) {
                HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) ambiguous link accepted (external depth): link %s at %s%s"LF,l,urladr,urlfil);
              } else {
                HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) forced to accept link (external depth): link %s at %s%s"LF,l,urladr,urlfil);
              }
              test_flush;
            }
            
          }
        }
      }  
      
      // filters
      {
        int jok;
        char* mdepth="";
        // filters, 0=sait pas 1=ok -1=interdit
        {
          int jokDepth1=0,jokDepth2=0;
          int jok1=0,jok2=0;
          jok1  = fa_strjoker(/*url*/0, _FILTERS,*_FILTERS_PTR,lfull,NULL,NULL,&jokDepth1);
          jok2 =  fa_strjoker(/*url*/0, _FILTERS,*_FILTERS_PTR,l,    NULL,NULL,&jokDepth2);
          if (jok2 == 0) {      // #2 doesn't know
            jok = jok1;        // then, use #1
            mdepth = _FILTERS[jokDepth1];
          } else if (jok1 == 0) { // #1 doesn't know
            jok = jok2;        // then, use #2
            mdepth = _FILTERS[jokDepth2];
          } else if (jokDepth1 >= jokDepth2) { // #1 matching rule is "after" #2, then it is prioritary
            jok = jok1;
            mdepth = _FILTERS[jokDepth1];
          } else {                             // #2 matching rule is "after" #1, then it is prioritary
            jok = jok2;
            mdepth = _FILTERS[jokDepth2];
          }
        }
        
        if (jok == 1) {   // autorisé
          filters_answer=1;  // décision prise par les filtres
          question=0;    // ne pas poser de question, autorisé
          forbidden_url=0;  // URL autorisée
          may_set_prio_to=0;    // clear may-set flag
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) explicit authorized (%s) link: link %s at %s%s"LF,mdepth,l,urladr,urlfil);
            test_flush;
          }
        } else if (jok == -1) {  // forbidden
          filters_answer=1;  // décision prise par les filtres
          question=0;    // ne pas poser de question:
          forbidden_url=1;   // URL interdite
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) explicit forbidden (%s) link: link %s at %s%s"LF,mdepth,l,urladr,urlfil);
            test_flush;
          }
        }  // sinon on touche à rien
      }
    }
    
    // vérifier mode mirror links
    if (question) {
      if (opt->mirror_first_page) {    // mode mirror links
        if (liens[ptr]->precedent==0) {  // parent=primary!
          forbidden_url=0;    // autorisé
          may_set_prio_to=0;    // clear may-set flag
          question=1;         // résolution auto
          force_mirror=5;     // mirror (5)
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) explicit mirror link: link %s at %s%s"LF,l,urladr,urlfil);
            test_flush;
          }
        }
      }
    }
    
    // on doit poser la question.. peut on la poser?
    // (oui je sais quel preuve de délicatesse, merci merci)      
    if ((question) && (ptr>0) && (!force_mirror)) {
      if (opt->wizard==2) {    // éliminer tous les liens non répertoriés comme autorisés (ou inconnus)
        question=0;
        forbidden_url=1;
        if ((opt->debug>1) && (opt->log!=NULL)) {
          HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) ambiguous forbidden link: link %s at %s%s"LF,l,urladr,urlfil);
          test_flush;
        }
      }
    }
    
    // vérifier robots.txt
    if (opt->robots) {
      int r = checkrobots(_ROBOTS,adr,fil);
      if (r == -1) {    // interdiction
#if DEBUG_ROBOTS
        printf("robots.txt forbidden: %s%s\n",adr,fil);
#endif
        // question résolue, par les filtres, et mode robot non strict
        if ((!question) && (filters_answer) && (opt->robots == 1) && (forbidden_url!=1)) {
          r=0;    // annuler interdiction des robots
          if (!forbidden_url) {
            if ((opt->debug>1) && (opt->log!=NULL)) {
              HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"Warning link followed against robots.txt: link %s at %s%s"LF,l,adr,fil);
              test_flush;
            }
          }
        }
        if (r == -1) {    // interdire
          forbidden_url=1;
          question=0;
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(robots.txt) forbidden link: link %s at %s%s"LF,l,adr,fil);
            test_flush;
          }
        }
      }
    }
    
    if (!question) {
      if ((opt->debug>1) && (opt->log!=NULL)) {
        if (!forbidden_url) {
          HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) shared foreign domain link: link %s at %s%s"LF,l,urladr,urlfil);
        } else {
          HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"(wizard) cancelled foreign domain link: link %s at %s%s"LF,l,urladr,urlfil);
        }
        test_flush;
      }
#if BDEBUG==3
      printf("at %s in %s, wizard says: url %s ",urladr,urlfil,l);
      if (forbidden_url) printf("cancelled"); else printf(">SHARED<");
      printf("\n");
#endif 
    }

    /* en cas de question, ou lien primaire (enregistrer autorisations) */
    if (question || (ptr==0)) {
      const char* s;
      int n=0;
      
      // si primaire (plus bas) alors ...
      if ((ptr!=0) && (force_mirror==0)) {
        char BIGSTK tempo[HTS_URLMAXSIZE*2];
        tempo[0]='\0';
        strcatbuff(tempo,adr);
        strcatbuff(tempo,fil);
        s = RUN_CALLBACK1(opt, query3, tempo);
        if (strnotempty(s)==0)  // entrée
            n=0;
          else if (isdigit((unsigned char)*s))
            sscanf(s,"%d",&n);
          else {
            switch(*s) {
            case '*': n=-1; break;
            case '!': n=-999; {
              /*char *a;
              int i;                                    
              a=copie_de_adr-128;
              if (a<r.adr) a=r.adr;
              for(i=0;i<256;i++) {
                if (a==copie_de_adr) printf("\nHERE:\n");
                printf("%c",*a++);
              }
              printf("\n\n");
              */
                      }
              break;
            default: n=-999; printf("What did you say?\n"); break;
              
            } 
          }
        io_flush;
      } else {   // lien primaire: autoriser répertoire entier       
        if (!force_mirror) {
          if ((opt->seeker & 1)==0) {  // interdiction de descendre
            n=7;
          } else {
            n=5;   // autoriser miroir répertoires descendants (lien primaire)
          }
        } else   // forcer valeur (sub-wizard)
          n=force_mirror;
      }
      
      /* sanity check - reallocate filters HERE */
      if ((*_FILTERS_PTR) + 1 >= opt->maxfilter) {
        opt->maxfilter += HTS_FILTERSINC;
        if (filters_init(&_FILTERS, opt->maxfilter, HTS_FILTERSINC) == 0) {
          printf("PANIC! : Too many filters : >%d [%d]\n", (*_FILTERS_PTR),__LINE__);
          fflush(stdout);
          if (opt->log) {
            fprintf(opt->log,LF"Too many filters, giving up..(>%d)"LF, (*_FILTERS_PTR) );
            fprintf(opt->log,"To avoid that: use #F option for more filters (example: -#F5000)"LF);
            test_flush;
          }
          assertf("too many filters - giving up" == NULL);    // wild..
        }
      }

      // here we have enough room for a new filter if necessary
      switch(n) {
      case -1: // sauter tout le reste
        forbidden_url=1;
        opt->wizard=2;    // sauter tout le reste
        break;
      case 0:    // interdire les mêmes liens: adr/fil
        forbidden_url=1; 
        HT_INSERT_FILTERS0;    // insérer en 0
        strcpybuff(_FILTERS[0],"-");
        strcatbuff(_FILTERS[0],jump_identification(adr));
        if (*fil!='/') strcatbuff(_FILTERS[0],"/");
        strcatbuff(_FILTERS[0],fil);
        break;
        
      case 1: // éliminer répertoire entier et sous rép: adr/path/ *
        forbidden_url=1;
        {
          size_t i = strlen(fil)-1;
          while((fil[i]!='/') && (i>0)) i--;
          if (fil[i]=='/') {
            HT_INSERT_FILTERS0;    // insérer en 0
            strcpybuff(_FILTERS[0],"-");
            strcatbuff(_FILTERS[0],jump_identification(adr));
            if (*fil!='/') strcatbuff(_FILTERS[0],"/");
            strncatbuff(_FILTERS[0] ,fil,i);
            if (_FILTERS[0][strlen(_FILTERS[0])-1]!='/') 
              strcatbuff(_FILTERS[0],"/");
            strcatbuff(_FILTERS[0],"*");
          }
        }            
        
        // ** ...
        break;
        
      case 2:    // adresse adr*
        forbidden_url=1;
        HT_INSERT_FILTERS0;    // insérer en 0                                
        strcpybuff(_FILTERS[0],"-");
        strcatbuff(_FILTERS[0],jump_identification(adr));
        strcatbuff(_FILTERS[0],"*");
        break;
        
      case 3: // ** A FAIRE
        forbidden_url=1;
        /*
        {
        int i=strlen(adr)-1;
        while((adr[i]!='/') && (i>0)) i--;
        if (i>0) {
        
          }
          
      }*/
        
        break;
        //
      case 4:    // same link
        // PAS BESOIN!!
        /*HT_INSERT_FILTERS0;    // insérer en 0                                
        strcpybuff(_FILTERS[0],"+");
        strcatbuff(_FILTERS[0],adr);
        if (*fil!='/') strcatbuff(_FILTERS[0],"/");
        strcatbuff(_FILTERS[0],fil);*/
        
        
        // étant donné le renversement wizard/primary filter (les primary autorisent up/down ET interdisent)
        // il faut éviter d'un lien isolé effectue un miroir total..
        
        *set_prio_to = 0+1;    // niveau de récursion=0 (pas de miroir)
        
        break;
        
      case 5:    // autoriser répertoire entier et fils
        if ((opt->seeker & 2)==0) {  // interdiction de monter
          size_t i = strlen(fil)-1;
          while((fil[i]!='/') && (i>0)) i--;
          if (fil[i]=='/') {
            HT_INSERT_FILTERS0;    // insérer en 0                                
            strcpybuff(_FILTERS[0],"+");
            strcatbuff(_FILTERS[0],jump_identification(adr));
            if (*fil!='/') strcatbuff(_FILTERS[0],"/");
            strncatbuff(_FILTERS[0],fil,i+1);
            strcatbuff(_FILTERS[0],"*");
          }
        } else {    // autoriser domaine alors!!
          HT_INSERT_FILTERS0;    // insérer en 0                                strcpybuff(filters[filptr],"+");
          strcpybuff(_FILTERS[0],"+");
          strcatbuff(_FILTERS[0],jump_identification(adr));
          strcatbuff(_FILTERS[0],"*");
        }
        break;
        
      case 6:    // same domain
        HT_INSERT_FILTERS0;    // insérer en 0                                strcpybuff(filters[filptr],"+");
        strcpybuff(_FILTERS[0],"+");
        strcatbuff(_FILTERS[0],jump_identification(adr));
        strcatbuff(_FILTERS[0],"*");
        break;
        //
      case 7:    // autoriser ce répertoire
        {
          size_t i = strlen(fil)-1;
          while((fil[i]!='/') && (i>0)) i--;
          if (fil[i]=='/') {
            HT_INSERT_FILTERS0;    // insérer en 0                                
            strcpybuff(_FILTERS[0],"+");
            strcatbuff(_FILTERS[0],jump_identification(adr));
            if (*fil!='/') strcatbuff(_FILTERS[0],"/");
            strncatbuff(_FILTERS[0],fil,i+1);
            strcatbuff(_FILTERS[0],"*[file]");
          }
        }
        
        break;
        
      case 50:    // on fait rien
        break;
      }  // switch 
                              
    }  // test du wizard sur l'url
  }  // fin du test wizard..

  // -------------------- PHASE 5 --------------------

  // lien non autorisé, peut-on juste le tester?
  if (just_test_it) {
    if (forbidden_url==1) {
      if (opt->travel&256) {    // tester tout de même
        if (strfield(adr,"ftp://")==0
#if HTS_USEMMS
					&& strfield(adr,"mms://")==0
#endif
					) {    // PAS ftp!
          forbidden_url=1;    // oui oui toujours interdit (note: sert à rien car ==1 mais c pour comprendre)
          *just_test_it=1;     // mais on teste
          if ((opt->debug>1) && (opt->log!=NULL)) {
            HTS_LOG(opt,LOG_DEBUG); fprintf(opt->log,"Testing link %s%s"LF,adr,fil);
          }
        }
      }
    }
    //adr[0]='\0';  // cancel
  }

  // -------------------- FINAL PHASE --------------------
  // Test if the "Near" test won
  if (may_set_prio_to && forbidden_url == 0) {
    *set_prio_to = may_set_prio_to;
  }

  return forbidden_url;
#undef _FILTERS
#undef _FILTERS_PTR
#undef _ROBOTS
}
Exemple #12
0
// forme à partir d'un lien et du contexte (origin_fil et origin_adr d'où il est tiré) adr et fil
// [adr et fil sont des buffers de 1ko]
// 0 : ok
// -1 : erreur
// -2 : protocole non supporté (ftp)
int ident_url_relatif(const char *lien, const char *origin_adr,
                      const char *origin_fil,
                      lien_adrfil* const adrfil) {
  int ok = 0;
  int scheme = 0;

  assertf(adrfil != NULL);

  adrfil->adr[0] = '\0';
  adrfil->fil[0] = '\0';                //effacer buffers

  // lien non vide!
  if (strnotempty(lien) == 0)
    return -1;                  // erreur!

  // Scheme?
  {
    const char *a = lien;

    while(isalpha((unsigned char) *a))
      a++;
    if (*a == ':')
      scheme = 1;
  }

  // filtrer les parazites (mailto & cie)
  // scheme+authority (//)
  if ((strfield(lien, "http://"))       // scheme+//
      || (strfield(lien, "file://"))    // scheme+//
      || (strncmp(lien, "//", 2) == 0)  // // sans scheme (-> default)
    ) {
    if (ident_url_absolute(lien, adrfil) == -1) {
      ok = -1;                  // erreur URL
    }
  } else if (strfield(lien, "ftp://")) {
    // Note: ftp:foobar.gif is not valid
    if (ftp_available()) {      // ftp supporté
      if (ident_url_absolute(lien, adrfil) == -1) {
        ok = -1;                // erreur URL
      }
    } else {
      ok = -2;                  // non supporté
    }
#if HTS_USEOPENSSL
  } else if (strfield(lien, "https://")) {
    // Note: ftp:foobar.gif is not valid
    if (ident_url_absolute(lien, adrfil) == -1) {
      ok = -1;                // erreur URL
    }
#endif
  } else if ((scheme) && ((!strfield(lien, "http:"))
                          && (!strfield(lien, "https:"))
                          && (!strfield(lien, "ftp:"))
             )) {
    ok = -1;                    // unknown scheme
  } else {                      // c'est un lien relatif
    // On forme l'URL complète à partie de l'url actuelle
    // et du chemin actuel si besoin est.

    // sanity check
    if (origin_adr == NULL || origin_fil == NULL 
      || *origin_adr == '\0' || *origin_fil == '\0') {
      return -1;
    }

    // copier adresse
    if (((int) strlen(origin_adr) < HTS_URLMAXSIZE)
        && ((int) strlen(origin_fil) < HTS_URLMAXSIZE)
        && ((int) strlen(lien) < HTS_URLMAXSIZE)) {

      /* patch scheme if necessary */
      if (strfield(lien, "http:")) {
        lien += 5;
        strcpybuff(adrfil->adr, jump_protocol_const(origin_adr));     // même adresse ; protocole vide (http)
      } else if (strfield(lien, "https:")) {
        lien += 6;
        strcpybuff(adrfil->adr, "https://");    // même adresse forcée en https
        strcatbuff(adrfil->adr, jump_protocol_const(origin_adr));
      } else if (strfield(lien, "ftp:")) {
        lien += 4;
        strcpybuff(adrfil->adr, "ftp://");      // même adresse forcée en ftp
        strcatbuff(adrfil->adr, jump_protocol_const(origin_adr));
      } else {
        strcpybuff(adrfil->adr, origin_adr);    // même adresse ; et même éventuel protocole
      }

      if (*lien != '/') {       // sinon c'est un lien absolu
        if (*lien == '\0') {
          strcpybuff(adrfil->fil, origin_fil);
        } else if (*lien == '?') {      // example: a href="?page=2"
          char *a;

          strcpybuff(adrfil->fil, origin_fil);
          a = strchr(adrfil->fil, '?');
          if (a)
            *a = '\0';
          strcatbuff(adrfil->fil, lien);
        } else {
          const char *a = strchr(origin_fil, '?');

          if (a == NULL)
            a = origin_fil + strlen(origin_fil);
          while((*a != '/') && (a > origin_fil))
            a--;
          if (*a == '/') {      // ok on a un '/'
            if ((((int) (a - origin_fil)) + 1 + strlen(lien)) < HTS_URLMAXSIZE) {
              // copier chemin
              strncpy(adrfil->fil, origin_fil, ((int) (a - origin_fil)) + 1);
              *(adrfil->fil + ((int) (a - origin_fil)) + 1) = '\0';

              // copier chemin relatif
              if (((int) strlen(adrfil->fil) + (int) strlen(lien)) < HTS_URLMAXSIZE) {
                strcatbuff(adrfil->fil, lien + ((*lien == '/') ? 1 : 0));
                // simplifier url pour les ../
                fil_simplifie(adrfil->fil);
              } else
                ok = -1;        // erreur
            } else {            // erreur
              ok = -1;          // erreur URL
            }
          } else {              // erreur
            ok = -1;            // erreur URL
          }
        }
      } else {                  // chemin absolu
        // copier chemin directement
        strcatbuff(adrfil->fil, lien);
        fil_simplifie(adrfil->fil);
      }                         // *lien!='/'
    } else
      ok = -1;

  }                             // test news: etc.

  // case insensitive pour adresse
  {
    char *a = jump_identification(adrfil->adr);

    while(*a) {
      if ((*a >= 'A') && (*a <= 'Z'))
        *a += 'a' - 'A';
      a++;
    }
  }

  // IDNA / RFC 3492 (Punycode) handling for HTTP(s)
  if (!link_has_authority(adrfil->adr) || strfield(adrfil->adr, "https:")) {
    char *const a = jump_identification(adrfil->adr);
    // Non-ASCII characters (theorically forbidden, but browsers are lenient)
    if (!hts_isStringAscii(a, strlen(a))) {
      char *const idna = hts_convertStringUTF8ToIDNA(a, strlen(a));
      if (idna != NULL) {
        if (strlen(idna) < HTS_URLMAXSIZE) {
          strcpybuff(a, idna);
        }
        free(idna);
      }
    }
  }

  return ok;
}