Logo Search packages:      
Sourcecode: weex version File versions  Download package

filedata.c

/***************************************************************************/
/*                                                                         */
/* Fast Webpage Exchanger - an FTP client for updating webpages            */
/* Copyright (C) 1999-2000 Yuuki NINOMIYA <gm@debian.or.jp>                */
/*                                                                         */
/* This program is free software; you can redistribute it and/or modify    */
/* it under the terms of the GNU General Public License as published by    */
/* the Free Software Foundation; either version 2, or (at your option)     */
/* any later version.                                                      */
/*                                                                         */
/* This program is distributed in the hope that it will be useful,         */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of          */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
/* GNU General Public License for more details.                            */
/*                                                                         */
/* You should have received a copy of the GNU General Public License       */
/* along with this program; if not, write to the                           */
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330,            */
/* Boston, MA 02111-1307, USA.                                             */
/*                                                                         */
/***************************************************************************/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif  

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <sys/stat.h>
#include "intl.h"
#include "strlib.h"
#include "variable.h"
#include "proto.h"

#ifndef PATH_MAX
#  define PATH_MAX 512
#endif /* PATH_MAX */


/* --------------------------------------------------
 NAME       get_local_file_data
 FUNCTION   get the data of local files
 INPUT      local_data ... pointer to stored date
 OUTPUT     the maximum number of local files
-------------------------------------------------- */
int get_local_file_data(FileData **local_data)
{
      DIR *dir;
      struct dirent *ent;
      struct stat file_stat;
      struct tm *ftime;
      char time_temp[10];
      char date_temp[10];
      int isdir;
      int file_num=0;
      int i;

      dir=opendir(".");
      while((ent=readdir(dir))!=NULL){
            if(strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0){
                  continue;
            }
            lstat(ent->d_name,&file_stat);

            /* follow symlinks */
            if (follow_symlinks[host_number] && (file_stat.st_mode & S_IFLNK)==S_IFLNK){
                  char realfname[PATH_MAX];

                  DebugPrint((stderr,"Local symlink is detected: %s\n",ent->d_name));
                  if(realpath(ent->d_name,realfname)==NULL){
                        char *temp;

                        fprintf(stderr,_("Cannot expand symbolic link `%s'. Ignore this file.\n"),ent->d_name);
                        temp=str_dup_printf(_("Expanding symbolic link failed: %s"),ent->d_name);
                        log_write(temp);
                        free(temp);
                        continue;
                  }
                  stat(realfname,&file_stat);
                  DebugPrint((stderr,"Realfname is %s\n",realfname));
            }
            isdir = ((file_stat.st_mode & S_IFDIR) == S_IFDIR);
            ftime=gmtime(&file_stat.st_mtime);

            if(isdir){
                  if(is_ignore_dir(ent->d_name,LOCAL)){
                        DebugPrint((stderr,"Ignore local dir: %s\n",ent->d_name));
                        continue;
                  }
            }else{
                  if(is_ignore_file(ent->d_name,LOCAL)){
                        DebugPrint((stderr,"Ignore local file: %s\n",ent->d_name));
                        continue;
                  }
            }

            sprintf(date_temp,"%04d%02d%02d",1900+ftime->tm_year,ftime->tm_mon+1,ftime->tm_mday);
            sprintf(time_temp,"%02d%02d%02d",ftime->tm_hour,ftime->tm_min,ftime->tm_sec);

            *local_data=str_realloc(*local_data,sizeof(**local_data)*(file_num+1));
            (*local_data)[file_num].date=atol(date_temp);
            (*local_data)[file_num].time=atol(time_temp);
            (*local_data)[file_num].isdir=isdir;
            (*local_data)[file_num].name=str_dup(ent->d_name);

            DebugPrint((stderr,"Local: [%08ld] [%06ld] [%08o] [%d] [%s]\n",(*local_data)[file_num].date,(*local_data)[file_num].time,file_stat.st_mode,(*local_data)[file_num].isdir,(*local_data)[file_num].name));

            if(conv_to_lower[host_number]){
                  for(i=0;i<file_num;i++){
                        if(strcasecmp((*local_data)[file_num].name,(*local_data)[i].name)==0){
                              char *temp;

                              fprintf(stderr,_("ConvToLower causes a conflict between `%s' and `%s'. Proceed anyway.\n"),(*local_data)[i].name,(*local_data)[file_num].name);

                              temp=str_dup_printf(_("Confliction by ConvToLower: %s"),(*local_data)[i].name);
                              log_write(temp);
                              free(temp);
                        }
                  }
            }

            file_num++;
      }
      closedir(dir);
      return(file_num);
}


/* --------------------------------------------------
 NAME       get_remote_file_data
 FUNCTION   get the data of remote files
 INPUT      remote_data ... pointer to stored date
 OUTPUT     the maximum number of remote files
-------------------------------------------------- */
int get_remote_file_data(FileData **remote_data)
{
      char list_temp[32];
      int  fd;
      FILE *fp;
      char *fgets_temp;
      char *file_name;
      long date,time;
      char mod_temp[20];
      char dir_flag;
      char *temp;
      int *add_cache_num=NULL;
      int add_cache_files=0;
      int file_num=0;
      int i;

      if(strcmp(current_dir[REMOTE],dest_dir[host_number])!=0){
            change_dir_actually(REMOTE);
      }
      strcpy(list_temp, "/tmp/weexXXXXXX");
      fd=mkstemp(list_temp);
      if(fd==-1){
            fprintf(stderr,_("Cannot create a unique file name.\n"));
            ftp_disconnect();
            exit(1);
      }

      if((show_hidden_file[host_number] && FtpDir(list_temp,"-a",ftp_buf)==0) ||
        (!show_hidden_file[host_number] && FtpDir(list_temp,NULL,ftp_buf)==0)){
            fprintf(stderr,_("Cannot get remote directory list.\n"));
            log_write(_("Getting remote directory list failed"));
            ftp_disconnect();
            exit(1);
      }
      fp=fdopen(fd,"r");
      if(fp==NULL){
            fprintf(stderr,_("Cannot open `%s'.\n"),list_temp);
            ftp_disconnect();
            exit(1);
      }

      while((fgets_temp=str_fgets(fp))!=NULL){
            if(strncmp(fgets_temp,"total",5)==0){
                  free(fgets_temp);
                  continue;
            }

            DebugPrint((stderr,"Remote: %s\n",fgets_temp));

            dir_flag=parse_file_and_filetype(fgets_temp,&file_name);

            free(fgets_temp);

            /*
              Test to which this entry is directory or file.
              This way is very dirty and slow.
            */
            if(dir_flag=='l'){
                  DebugPrint((stderr,"Remote symlink is detected: %s\n",file_name));
                  dir_flag=FtpChdir(file_name,ftp_buf) ? 'd' : '-';
                  FtpChdir(current_dir[REMOTE], ftp_buf);
                  DebugPrint((stderr,"Symlink type is '%c'\n",dir_flag));
            }

            if(strcmp(file_name,".")==0 ||
               strcmp(file_name,"..")==0 ||
               (dir_flag=='d' && is_ignore_dir(file_name,REMOTE)) ||
               (dir_flag!='d' && is_ignore_file(file_name,REMOTE)) ){
                  DebugPrint((stderr,"[%c] Ignore remote `%s'\n",dir_flag,file_name));
                  free(file_name);
                  continue;
            }

            date=time=0;
            if(dir_flag!='d'){
                  if(conv_to_lower[host_number]){
                        temp=str_tolower(file_name);
                        DebugPrint((stderr,"conv_to_lower from `%s' to `%s'\n",file_name,temp));
                        free(file_name);
                        file_name=temp;
                  }
                  if(get_cache(file_name,&date,&time)==-1){
                        DebugPrint((stderr,"No cache: %s\n",file_name));
                        if(FtpModDate(file_name,mod_temp,20,ftp_buf)==1){
                              date=n_atol(mod_temp,8);
                              time=n_atol(mod_temp+8,6);
                              add_cache_num=str_realloc(add_cache_num,sizeof(*add_cache_num)*(add_cache_files+1));
                              add_cache_num[add_cache_files++]=file_num;
                        }
                  }

            }

            *remote_data=str_realloc(*remote_data,sizeof(**remote_data)*(file_num+1));
            (*remote_data)[file_num].date=date;
            (*remote_data)[file_num].time=time;
            (*remote_data)[file_num].isdir=(dir_flag=='d');
            (*remote_data)[file_num].name=file_name;

            DebugPrint((stderr,"Remote: [%08ld] [%06ld] [%c] [%d] [%s]\n",(*remote_data)[file_num].date,(*remote_data)[file_num].time,dir_flag,(*remote_data)[file_num].isdir,(*remote_data)[file_num].name));

            file_num++;
      }

      for(i=0;i<add_cache_files;i++){
            update_cache((*remote_data)[add_cache_num[i]].name,(*remote_data)[add_cache_num[i]].date,(*remote_data)[add_cache_num[i]].time);
            DebugPrint((stderr,"Update cache `%s' : %ld %ld\n",(*remote_data)[add_cache_num[i]].name,(*remote_data)[add_cache_num[i]].date,(*remote_data)[add_cache_num[i]].time));
      }

      fclose(fp);
      if(remove(list_temp)==-1){
            fprintf(stderr,_("Cannot remove `%s'.\n"),list_temp);
            ftp_disconnect();
            exit(1);
      }
      free(add_cache_num);
      /* free(list_temp); */
      return(file_num);
}


/* --------------------------------------------------
 NAME       free_file_data
 FUNCTION   release memory stored file data
 INPUT      file_data ... file data
            max_file_data ... the maximum number of file data
 OUTPUT     none
-------------------------------------------------- */
void free_file_data(FileData *file_data,int max_file_data)
{
      int i;

      for(i=0;i<max_file_data;i++){
            free(file_data[i].name);
      }
      free(file_data);
}


/* --------------------------------------------------
 NAME       parse_file_and_filetype
 FUNCTION   parse file and filetype (whether dir) from file list
 INPUT      str .... file list (a single line)
            file ... pointer to stored file name
 OUTPUT     dir_flag ... directory is 'd'
                         symlink is 'l'
                         others are '-'
                         return -1 if error
-------------------------------------------------- */
int parse_file_and_filetype(char *str,char **file)
{
      char dir_flag;
      int i;
      char *ptr;
      char *lnktmp;

      ptr=strtok(str," ");
      if(ptr==NULL){
            fprintf(stderr,_("Cannot get the remote directory list correctly.\n"));
            ftp_disconnect();
            exit(1);
      }
      if(isdigit(*ptr) && isdigit(*(ptr+1)) && *(ptr+2)=='-'){    /* Remote system type is Windows_NT */
            for(i=0;i<2;i++){
                  if((ptr=strtok(NULL," "))==NULL){
                        fprintf(stderr,_("Cannot get the remote directory list correctly.\n"));
                        ftp_disconnect();
                        exit(1);
                  }
            }
            dir_flag=(strcmp(ptr,"<DIR>")==0) ? 'd' : '-';
      }else{      /* Remote system type is UNIX or MACOS */
            dir_flag=str[0];

            for(i=0;i<7;i++){
                  if((ptr=strtok(NULL," "))==NULL){
                        fprintf(stderr,_("Cannot get the remote directory list correctly.\n"));
                        ftp_disconnect();
                        exit(1);
                  }
                  if((i==0 && strcmp(ptr,"folder")==0) ||
                     (i==1 && strcmp(ptr,"0000/0000")==0) ||
                     (i==3 && isupper(*ptr) && islower(*(ptr+1)) && islower(*(ptr+2)) && *(ptr+3)=='\0')){
                        i++;
                  }
            }
      }
      ptr=ptr+strlen(ptr)+1;
      if((lnktmp=strstr(ptr," -> "))!=NULL){    /* This file is a symbolic link. */
            *lnktmp='\0';
      }

      /* Strip leading spaces from the filename which can occur
         with an FTP server based on Windows NT */
      while (*ptr == ' '){
            ptr++;
      }

      *file=str_dup(ptr);

      return(dir_flag);
}


/* --------------------------------------------------
 NAME       is_ignore_dir
 FUNCTION   whether ???IgnoreDir or not
 INPUT      dir_name ... name of the directory
            side ....... LOCAL or REMOTE
 OUTPUT     return 1 if match ???IgnoreDir otherwise return 0
-------------------------------------------------- */
int is_ignore_dir(char *dir_name,LocalOrRemote side)
{
      cfgList *l;
      char *temp;

      if((side==LOCAL && ignore_local_dir[host_number]==NULL) || (side==REMOTE && ignore_remote_dir[host_number]==NULL)){
            return(0);
      }
      temp=str_concat(current_dir[side],dir_name,"/",NULL);
      if(side==LOCAL){
            for(l=ignore_local_dir[host_number];l!=NULL;l=l->next){
                  if(cmp_file_with_wildcard(temp,l->str)==0){
                        free(temp);
                        return(1);
                  }
            }
      }else if(side==REMOTE){
            for(l=ignore_remote_dir[host_number];l!=NULL;l=l->next){
                  if(cmp_file_with_wildcard(temp,l->str)==0){
                        free(temp);
                        return(1);
                  }
            }
      }
      free(temp);
      return(0);
}


/* --------------------------------------------------
 NAME       is_ignore_file
 FUNCTION   whether ???IgnoreFile or not
 INPUT      file_name ... file name
            side ........ LOCAL or REMOTE
 OUTPUT     return 1 if match ???IgnoreFile otherwise return 0
-------------------------------------------------- */
int is_ignore_file(char *file_name,LocalOrRemote side)
{
      cfgList *l;
      char *temp;

      if((side==LOCAL && ignore_local_file[host_number]==NULL) || (side==REMOTE && ignore_remote_file[host_number]==NULL)){
            return(0);
      }
      temp=str_concat(current_dir[side],file_name,NULL);
      if(side==LOCAL){
            for(l=ignore_local_file[host_number];l!=NULL;l=l->next){
                  if(strchr(l->str,'/')==NULL){
                        if(cmp_file_with_wildcard(file_name,l->str)==0){
                              free(temp);
                              return(1);
                        }
                  }else{
                        if(cmp_file_with_wildcard(temp,l->str)==0){
                              free(temp);
                              return(1);
                        }
                  }
            }
      }else if(side==REMOTE){
            for(l=ignore_remote_file[host_number];l!=NULL;l=l->next){
                  if(strchr(l->str,'/')==NULL){
                        if(cmp_file_with_wildcard(file_name,l->str)==0){
                              free(temp);
                              return(1);
                        }
                  }else{
                        if(cmp_file_with_wildcard(temp,l->str)==0){
                              free(temp);
                              return(1);
                        }
                  }
            }
      }
      free(temp);
      return(0);
}


/* --------------------------------------------------
 NAME       is_ascii_file
 FUNCTION   whether AsciiFile or not
 INPUT      file_name ... file name
 OUTPUT     return 1 if match AsciiFile otherwise return 0
-------------------------------------------------- */
int is_ascii_file(char *file_name)
{
      cfgList *l;
      char *temp;

      if(ascii_file[host_number]==NULL){
            return(0);
      }
      temp=str_concat(current_dir[LOCAL],file_name,NULL);
      for(l=ascii_file[host_number];l!=NULL;l=l->next){
            if(strchr(l->str,'/')==NULL){
                  if(cmp_file_with_wildcard(file_name,l->str)==0){
                        free(temp);
                        return(1);
                  }
            }else{
                  if(cmp_file_with_wildcard(temp,l->str)==0){
                        free(temp);
                        return(1);
                  }
            }
      }
      free(temp);
      return(0);
}


/* --------------------------------------------------
 NAME       is_change_permission_dir
 FUNCTION   whether ChangePermissionDir or not
 OUTPUT     return 1 if match ChangePermissionDir otherwise return 0
-------------------------------------------------- */
int is_change_permission_dir(void)
{
      cfgList *l;

      if(change_permission_dir[host_number]==NULL){
            return(0);
      }
      for(l=change_permission_dir[host_number];l!=NULL;l=l->next){
            if(cmp_file_with_wildcard(current_dir[LOCAL],l->str)==0){
                  return(1);
            }
      }
      return(0);
}


/* --------------------------------------------------
 NAME       is_preserve_permission_dir
 FUNCTION   whether PreservePermissionDir or not
 OUTPUT     return 1 if match PreservePermissionDir otherwise return 0
-------------------------------------------------- */
int is_preserve_permission_dir(void)
{
      cfgList *l;

      if(preserve_permission_dir[host_number]==NULL){
            return(0);
      }
      for(l=preserve_permission_dir[host_number];l!=NULL;l=l->next){
            if(cmp_file_with_wildcard(current_dir[LOCAL],l->str)==0){
                  return(1);
            }
      }
      return(0);
}


/* --------------------------------------------------
 NAME       is_keep_remote_dir
 FUNCTION   whether KeepRemoteDir or not
 OUTPUT     return 1 if match KeepRemoteDir otherwise return 0
-------------------------------------------------- */
int is_keep_remote_dir(void)
{
      cfgList *l;

      if(keep_remote_dir[host_number]==NULL){
            return(0);
      }
      for(l=keep_remote_dir[host_number];l!=NULL;l=l->next){
            if(cmp_file_with_wildcard(current_dir[REMOTE],l->str)==0){
                  return(1);
            }
      }
      return(0);
}

Generated by  Doxygen 1.6.0   Back to index