#include #include #include #include #include #include #include #include #include #include "tool.h" #include "../common/commun.h" /* Obtient information sur un fichier dans la structure FILEINFO Retourne -1 si information innaccessible, 0 si ok */ int file_statinfo (const char *fpath, FILEINFO *info) { struct stat buf; int ret = -1; if (fpath[0] != '\0'){ ret = lstat ((char*)fpath,&buf); path_splitlex (fpath,NULL,info->name); if (ret != -1){ int mask = buf.st_mode & S_IFMT; long size = 0; FILETYPE type = FILETYPE_REG; if (mask == S_IFREG){ size = buf.st_size; type = FILETYPE_REG; }else if (mask == S_IFDIR){ size = buf.st_size/16; type = FILETYPE_DIR; }else if (mask == S_IFCHR){ type = FILETYPE_DEVCHR; }else if (mask == S_IFBLK){ type = FILETYPE_DEVBLK; }else if (mask == S_IFIFO){ type = FILETYPE_PIPE; }else if (mask == S_IFLNK){ type = FILETYPE_SYMLINK; } info->size = size; info->type = type; info->date = buf.st_mtime; info->inode = (int)buf.st_ino; info->device.major_num = major(buf.st_dev); info->device.minor_num = minor(buf.st_dev); } } return ret; } /* D‚termine la longueur et la date d'un fichier ou r‚pertoire Si le fichier est un r‚pertoire, retourne le nombre maximum de fichier qu'il peut contenir retourne -1 si trouve pas le fichier, 0 si ok */ export int file_info (const char *filnam, unsigned long *date, long *size) { FILEINFO info; int ret = file_statinfo (filnam,&info); if (ret != -1){ *size = info.size; *date = info.date;; } return (ret); } /* D‚termine la longueur et la date (format DOS) d'un fichier ou r‚pertoire Si le fichier est un r‚pertoire, retourne le nombre maximum de fichier qu'il peut contenir retourne -1 si trouve pas le fichier, 0 si ok */ export int file_infodos (const char *filnam, unsigned long *date, long *size) { int ret = file_info(filnam,date,size); if (ret != -1){ *date = date_unix2dos (*date); } return ret; } /* Retourne la longueur d'un fichier sans l'ouvrir retourne -1 si erreur */ export long file_size (const char *filnam) { long len; unsigned long date; if (file_info(filnam,&date,&len)==-1) len = -1; return (len); } #if 0 /* Retourne le type d'un fichier Retourne -1 si le fichier n'existe pas. Retourne 0 si fichier ordinaire 1 si le fichier est en fait un repertoire 2 si le fichier est un character device 3 si le fichier est un block device 4 si le fichier est un pipe Ne fonctionne pas avec wild card */ export int file_type (char const *pathname) { int ret = -1; if (pathname[0] == '\0' || strcmp(pathname,"/")==0){ ret = 1; }else{ struct stat buf; ret = stat ((char*)pathname,&buf); if (ret != -1){ int mask = buf.st_mode & S_IFMT; if (mask == S_IFREG){ ret = 0; }else if (mask == S_IFDIR){ ret = 1; }else if (mask == S_IFCHR){ ret = 2; }else if (mask == S_IFBLK){ ret = 3; }else if (mask == S_IFIFO){ ret = 4; } } } return ret; } /* D‚termine si un fichier (au moins un) existe Retourne != 0 si au moins un, 0 sinon Les entr‚es . et .. sont ignor‚s ainsi que les r‚pertoires. Si pathname est un r‚pertoire, c'est comme si il n'existe pas vue de cette fonction. Fonctionne avec wild card */ export bool file_exist (char const *pathname) { int ret = 0; if (file_iswild (pathname)){ char *tb[2]; int nb = dir_getlistp(pathname,0,tb,1); tbstr_free (tb,nb); ret = nb > 0; }else{ ret = file_type(pathname)==0; } return ret; } #endif /* Renomme un fichier Permet aussi de relocaliser un fichier dans un autre directory Retourne 0 si ok, -1 si erreur */ export int file_rename (const char *present, const char *nouveau) { int ret = -1; if (file_type(nouveau)<0){ ret = rename (present,nouveau); } return ret; } /* Change l'extension du nom d'un fichier oldfile et newfile peuvent etre identique newext peut etre vide, cela produit un fichier sans extension ni point */ export void file_chgext ( const char *oldfile, /* fichier a renommer */ char *newfile, /* contiendra le r‚sultat */ const char *newext) /* extension pour remplacer celle de oldfile */ /* commence par un . ou pas */ { char *pt = newfile; char *trouve = NULL; strcpy (newfile,oldfile); /* Trouve le dernier point du path */ /* Il peut y avoir des r‚pertoire avec extension /dir/dir.1/fichier.c */ while (*pt != '\0'){ if (path_issep(*pt)) trouve = NULL; if (*pt == '.' && *(pt+1) != '/' && *(pt+1) != '.') trouve = pt; pt++; } if (trouve != NULL) pt = trouve; if (*newext != '\0'){ *pt ++ = '.'; if (*newext == '.') newext++; strcpy (pt,newext); }else{ *pt = '\0'; } } /* Renomme un fichier en ne changeant que l'extension Si un fichier possedant une telle extension existe deja, force indique si l'on doit faire l'operation tout de meme Retourne 0 si ok, -1 si erreur */ export int file_renameext (const char *nomfch, const char *ext, int force) { char newnam[MAXSIZ_PATH]; int typef; file_chgext (nomfch,newnam,ext); typef = file_type(newnam); if (typef == 1 || (typef == 0 && !force)) return (-1); if (typef == 0) unlink (newnam); return (file_rename (nomfch,newnam)); } /* Compare l'extension d'un fichier avec un extension Retourne < 0, 0 ou > 0 comme strcmp */ export int file_cmpext ( const char *fname, const char *extcmp) /* Extension avec ou sans point */ { char ext[MAXSIZ_EXTENSION]; file_baseext (fname,NULL,ext); if (extcmp[0] == '.') extcmp++; return stricmp(ext,extcmp); } #ifdef TEST #include static void tst (char *path) { int type = file_type(path); printf ("%20s --> %d",path,type); if (type != -1){ FILEINFO info; file_statinfo (path,&info); printf (" size %d date %d inode %d device %d" ,info.size,info.date,info.inode,info.device); } printf ("\n"); } static void near exist (char *name) { printf ("exist :%s: -> %s\n",name,file_exist(name)? "ok" : "non"); } int main (int argc, char *argv[]) { if (argc == 4 && strcmp(argv[1],"ren")==0){ printf ("Renomme :%s: -> :%s: statut %d\n",argv[2],argv[3] ,file_rename(argv[2],argv[3])); }else if (argc == 1){ exist ("*.lib"); exist ("*.c"); exist ("file.c"); printf ("file size de file.c = %ld\n",file_size("file.c")); printf ("file size de /usr/prj = %ld\n",file_size("/usr/prj")); tst (""); tst ("/tmp/tty1a.0"); tst ("/"); tst ("/usr/pierre"); tst ("/u"); tst ("/home/solucor/jack/commun.mak"); } return 0; } #endif