/* file.c: open/close files recognising certain extensions. */ #include #include #include "file.h" #include "pools.h" #include "error.h" /* opens a file with given name and fopen() open_mode ("w" or "r" e.g.). Returns the * FILE * or NULL if opening the file was not succesful. Returns in ispipe whether * or not the file has been opened through a pipe. File extensions * .Z, .gz, .bz and .bz2 are recognised and lead to piped input/output with the * proper compress/uncompress commands. Also if the first character of the file name is * equal to '|', the file name is opened as a pipe. */ FILE *OpenFile(char *filename, char *open_mode, int *ispipe) { FILE *fp = (FILE *)NULL; if ((*open_mode != 'r' && *open_mode != 'w' && *open_mode != 'a')) { Error("OpenFile", "Invalid fopen() mode '%s'\n", open_mode ? open_mode : "(null)"); return fp; } if (filename[0] != '\0' && filename[strlen(filename)-1] != '/') { char *cmd = Alloc(strlen(filename) + 20); char *ext = strrchr(filename, '.'); if (filename[0] == '|') { sprintf(cmd, "%s", filename+1); fp = popen(cmd, open_mode); *ispipe = TRUE; } else if (ext && strcmp(ext, ".gz")==0) { if (*open_mode == 'r') sprintf(cmd, "gunzip < %s", filename); else sprintf(cmd, "gzip > %s", filename); fp = popen(cmd, open_mode); *ispipe = TRUE; } else if (ext && strcmp(ext, ".Z")==0) { if (*open_mode == 'r') sprintf(cmd, "uncompress < %s", filename); else sprintf(cmd, "compress > %s", filename); fp = popen(cmd, open_mode); *ispipe = TRUE; } else if (ext && strcmp(ext, ".bz")==0) { if (*open_mode == 'r') sprintf(cmd, "bunzip < %s", filename); else sprintf(cmd, "bzip > %s", filename); fp = popen(cmd, open_mode); *ispipe = TRUE; } else if (ext && strcmp(ext, ".bz2")==0) { if (*open_mode == 'r') sprintf(cmd, "bunzip2 < %s", filename); else sprintf(cmd, "bzip2 > %s", filename); fp = popen(cmd, open_mode); *ispipe = TRUE; } else { fp = fopen(filename, open_mode); *ispipe = FALSE; } Free(cmd, strlen(filename) + 20); if (!fp) { Error(NULL, "Can't open file '%s' for %s", filename, *open_mode == 'r' ? "reading" : "writing"); } return fp; } return (FILE *)NULL; } /* closes the file taking into account whether or not it is a pipe */ void CloseFile(FILE *fp, int ispipe) { if (fp) { /* close the file */ if (ispipe) pclose(fp); else fclose(fp); } }