tinycobol/cobroutines/dir.c

306 lines
6.0 KiB
C

/*
* Copyright (C) 2003 Wesley Oliveira, Aline Oliveira, Hudson Reis.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1,
* or (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING.LIB. If
* not, write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <windows.h>
#include <sys/stat.h>
#define OK 0
#define ERRO 1
#define NDATA -1
#ifdef __MSVCRT__
#define cbl_BARRA "\\"
#else
#define cbl_BARRA "/"
#endif
typedef unsigned int cbl_t;
DIR *current_directory;
struct dirent *current_file;
/* Prototypes */
cbl_t cbl_open_dir(char *directory);
cbl_t cbl_rewind_dir();
cbl_t cbl_read_dir(char *file);
cbl_t cbl_close_dir();
cbl_t cbl_remove_file(char *file);
void cbl_sleep(unsigned int *time);
cbl_t cbl_copy_dir(char *entrada, char *saida);
cbl_t cbl_create_dir(char *dados, int mode);
cbl_t cbl_delete_dir(char *dados);
cbl_t cbl_move_dir(char *origem, char *destino);
cbl_t cbl_copy_file(char *entrada, char *saida);
cbl_t cbl_delete_file(char *arquivo);
int cbl_align(char *);
/* Functions */
void cbl_sleep(unsigned int *time) {
Sleep(*time);
return;
}
cbl_t cbl_open_dir(char *directory) {
char name[256];
int p;
if(current_directory) // close the current directory before
closedir(current_directory);
p = 0;
while(p<256 && *(directory+p) != ' ') {
name[p] = *(directory+p);
p++;
}
name[p] = 0;
current_directory = opendir(name);
if(!current_directory)
return ERRO;
return OK;
}
cbl_t cbl_rewind_dir() {
if(!current_directory)
return ERRO;
rewinddir(current_directory);
return OK;
}
cbl_t cbl_read_dir(char *file) {
int i;
if(!current_directory)
return ERRO;
current_file = readdir(current_directory);
if(!current_file)
return ERRO;
i = 0;
while(current_file->d_name[i]) {
*(file + i) = current_file->d_name[i];
i++;
}
return OK;
}
cbl_t cbl_close_dir() {
if(!current_directory) // close the current directory before
return ERRO;
closedir(current_directory);
return OK;
}
cbl_t cbl_remove_file(char *file) {
char name[256];
int p;
p = 0;
while(p<256 && *(file+p) != ' ') {
name[p] = *(file+p);
p++;
}
name[p] = 0;
if(unlink(&name[0])==0)
return OK;
return ERRO;
}
cbl_t cbl_copy_dir(char *entrada, char *saida)
{
DIR *dir_a,*dir_b;
struct dirent *arquivo;
char *bufr, *bufs;
//cbl_t d;
if(*entrada){
if(cbl_align(entrada)==ERRO) return(1);
if(cbl_align(saida)==ERRO) return(1);
} else {
return(ERRO);
}
bufr = (char *) malloc(sizeof(char)*(strlen(entrada)+100));
if(!bufr) {
return(4);
}
bufs = (char *) malloc(sizeof(char)*(strlen(saida) +100));
if(!bufs) {
return(4);
}
if ( (dir_a = opendir(entrada)) == NULL ) {
return(2);
}
if((dir_b = opendir(saida)) != NULL) {
closedir(dir_a);
closedir(dir_b);
return(3);
}
else {
cbl_create_dir(saida,0766);
while( (arquivo=readdir(dir_a)) ) {
strcpy(bufr,saida);
strcpy(bufs,entrada);
strcat(bufr,cbl_BARRA);
strcat(bufs,cbl_BARRA);
if( !strcmp(arquivo->d_name,".") ) {
continue;
}
else
if( !strcmp(arquivo->d_name,"..") ) {
continue;
}
strcat(bufr,arquivo->d_name);
strcat(bufs,arquivo->d_name);
cbl_copy_file(bufs,bufr);
}
}
closedir(dir_a);
free(bufr);
free(bufs);
return(OK);
}
cbl_t cbl_create_dir(char *dados, int mode)
{
DIR *dir;
if(*dados) {
if(cbl_align(dados)==ERRO){ return(1); }
}
else {
return(1);
}
if( (dir = opendir(dados)) != NULL ) {
return ERRO;
}
// Nilo, 23rd april 2007
// Aparently MINGW doesn't accept two parameters for mkdir....
// if(mkdir(dados, mode) == -1){
if(mkdir(dados) == -1) {
return ERRO;
}
chmod(dados,mode);
return(OK);
}
cbl_t cbl_delete_dir(char *dados)
{
DIR *dir;
struct dirent *file;
if(*dados) {
if(cbl_align(dados)==ERRO) {
return(1);
}
}
else {
return(1);
}
if( (dir = opendir(dados)) == NULL) {
return(2);
}
closedir(dir);
if( rmdir(dados) == 0 ) { /* Nao existe nada no diretorio */
return(OK);
}
else { /* Aqui existe arquivos no diretorio
* entao sao apagados e ai depois apaga
* o diretorio.
*/
dir = opendir(dados);
while( (file = readdir(dir)) ) {
chdir(dados);
cbl_delete_file(file->d_name);
}
closedir(dir);
chdir("..");
if ( rmdir(dados) != 0 ) {
return(ERRO);
}
}
return(OK);
}
cbl_t cbl_move_dir(char *origem, char *destino)
{
DIR *dir;
//cbl_t d;
if ( (!*origem) || (!*destino) ) {
return(1);
}
if ( cbl_align(origem) == ERRO ) {
return(1);
}
if ( cbl_align(destino) == ERRO ) {
return(1);
}
if ( (dir = opendir(destino)) != NULL ) {
closedir(dir);
return(ERRO);
}
if ( cbl_copy_dir(origem,destino) == OK ) {
if( cbl_delete_dir(origem) != OK ) {
return(ERRO);
}
}
else {
return(ERRO);
}
return(OK);
}
cbl_t cbl_change_dir(char *path) {
if ( cbl_align(path) != 0 ) {
return 1;
}
if ( chdir(path) != 0 ) {
return 2;
}
return 0;
}
void cbl_get_current_dir(char *path, cbl_t *retorno) {
*retorno = 0;
if ( getcwd(path, 1024) == NULL ) {
*retorno = 1;
}
}