// -------------------------------------------------------------------- // a t t a c h . c p p // // Fido messages tracker // work with attached files // -------------------------------------------------------------------- // Copyright (c) 1998-2000 by Fyodor Ustinov // FIDONet 2:5020/79 // // All rights reserved. // -------------------------------------------------------------------- #include #include #ifndef UNIX #include #endif #if defined (UNIX) || defined(__DJGPP__) #include #endif #if defined(__DJGPP__) #include #endif #include #include #include #include #include #include #include "constant.hpp" #include "help.hpp" #include "utils.hpp" #include "vars.hpp" #include "configure.hpp" #include "fidoaddr.h" #include "scandir.hpp" #include "attach.hpp" #include "outbound.hpp" #include "ufmtypes.h" #include "msg.hpp" #ifndef O_BINARY #define O_BINARY 0 #endif #ifdef __NT__ #undef byte #undef EXPENTRY #include #endif // -------------------------------------------------------------------- static char NewPath[1024]; static char NewSubj[1024]; static int AttSize; // -------------------------------------------------------------------- static char *FullName(char *name) { static char Buff[1024]; if (FileInbound != NULL) { strcpy(Buff,FileInbound); } else { Buff[0] = '\0'; } if (strchr(name,PATHDELIMC) == NULL #ifndef UNIX && strchr(name,':') == NULL #endif ) { strcat(Buff,name); } else { strcpy(Buff,name); } return Buff; } int _PrintAttach(char *Buff) { Log.Level(LOGI) << "Attached '" << FullName(Buff) << "'" << EOL; return TRUE; } int _AttToSize(char *Buff) { int i; int fh; char *tmt; tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); #endif fh = open(tmt,O_RDONLY | O_BINARY); #ifdef __NT__ CharToOem(tmt,tmt); #endif i = errno; if (fh == -1) { if (i != ENOENT) { Log.Level(LOGE) << " Unable to open file: '" << tmt << "', Errno: " << i << EOL; return FALSE; } else { return TRUE; } } i = filelength(fh); if (i == -1) { i = errno; close(fh); Log.Level(LOGE) << " Unable to get size of file: '" << tmt << "', Errno: " << i << EOL; return FALSE; } close(fh); AttSize += i; return TRUE; } int _AddToLo(char *Buff) { char tmt[1024]; tmt[0] = NewPath[0]; tmt[1] = '\0'; strcat(tmt,FullName(Buff)); AddToLo(tmt); return TRUE; } int _DelFromLo(char *Buff) { DelFromLo(FullName(Buff)); return TRUE; } int _ChangePath(char *Buff) { char *tmt; strcat(NewSubj,NewPath); if ((tmt = strrchr(Buff,PATHDELIMC)) != NULL) { tmt++; #ifndef UNIX } else if ((tmt = strrchr(Buff,':')) != NULL) { tmt++; #endif } else { tmt = Buff; } strcat(NewSubj,tmt); strcat(NewSubj," "); return TRUE; } int _DeleteAttach(char *Buff) { char *tmt; tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); #endif if (access(tmt,F_OK) != 0) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " File not found: '" << tmt << "'" << EOL; return TRUE; } if (unlink(tmt) != 0) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGE) << " Unable to delete: '" << tmt << "'" << EOL; return FALSE; } #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " Delete: '" << tmt << "'" << EOL; return TRUE; } int _AttachExists(char *Buff) { struct stat dd; char *tmt; tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); #endif if (stat(tmt,&dd) != 0) return FALSE; if (!S_ISREG(dd.st_mode)) return FALSE; #ifdef __MINGW32__ if (SkipHiddenFiles) { struct _finddata_t fd; int h = _findfirst(tmt, &fd); if (h != -1) { _findclose(h); if (!strcmp(fd.name, tmt) && (fd.attrib|_A_HIDDEN)) return FALSE; } } #elif defined(__DJGPP__) if (SkipHiddenFiles) { unsigned int attrs; _dos_getfileattr(tmt, &attrs); if (attrs|_A_HIDDEN) return FALSE; } #elif !defined(UNIX) if (SkipHiddenFiles && (dd.st_attr & 2)) return FALSE; #endif return TRUE; } int _MoveAttach(char *Buff) { char *tmt; char B[1024]; tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); #endif if (access(tmt,F_OK) != 0) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " File not found: '" << tmt << "'" << EOL; return TRUE; } strcpy(B,NewPath); if ((tmt = strrchr(Buff,PATHDELIMC)) != NULL) { tmt++; #ifndef UNIX } else if ((tmt = strrchr(Buff,':')) != NULL) { tmt++; #endif } else { tmt = Buff; } strcat(B,tmt); tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); OemToChar(B,B); #endif if (!FileMove(B,tmt)) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGE) << " Unable to move file '" << tmt << "' to " << NewPath << EOL; return FALSE; } #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " Move: '" << tmt << "' ==> " << NewPath << EOL; return TRUE; } int _CopyAttach(char *Buff) { char *tmt; char B[1024]; tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); #endif if (access(tmt,F_OK) != 0) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " File not found: '" << tmt << "'" << EOL; return TRUE; } strcpy(B,NewPath); if ((tmt = strrchr(Buff,PATHDELIMC)) != NULL) { tmt++; #ifndef UNIX } else if ((tmt = strrchr(Buff,':')) != NULL) { tmt++; #endif } else { tmt = Buff; } strcat(B,tmt); tmt = FullName(Buff); #ifdef __NT__ OemToChar(tmt,tmt); OemToChar(B,B); #endif if (!FileCopy(B,tmt)) { #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGE) << " Unable to copy file '" << tmt << "' to " << NewPath << EOL; return FALSE; } #ifdef __NT__ CharToOem(tmt,tmt); #endif Log.Level(LOGI) << " Copy: '" << tmt << "' ==> " << NewPath << EOL; return TRUE; } // -------------------------------------------------------------------- #if defined(UNIX) || defined(__EMX__) typedef int (*faff)(char *b); int ForAllFiles(faff Action,cMSG &m) { #else int ForAllFiles(int (*Action)(char *Fname),cMSG &m) { #endif // For all Files attached to message do Action. // return Action value. // Action - int Action(char *FName); char Buff[73]; char *tmt; if (m._Subject == NULL) { return FALSE; } if (strlen(m._Subject) == 0) { return FALSE; } memset(Buff,0,73); strncpy(Buff,m._Subject,72); tmt = Buff; while (*tmt == ' ') tmt++; if (*tmt == '\0') return FALSE; while (*tmt != '\0') { while (*tmt == ' ') tmt++; if (*tmt == '\0') break; int i; i = FALSE; if (strchr(tmt,' ') != NULL) { i = TRUE; *strchr(tmt,' ') = '\0'; } if (!Action(tmt)) return FALSE; while (*tmt != '\0') tmt++; if (i) tmt++; } return TRUE; } // -------------------------------------------------------------------- int PrintAttach(cMSG &m) { return ForAllFiles(&_PrintAttach,m); } int AddAttachToLo(cMSG &m) { NewPath[0] = '\0'; if (m.fTFS) { NewPath[0] = '#'; } if (m.fKFS) { NewPath[0] = '^'; } return ForAllFiles(&_AddToLo,m); } int DelAttachFromLo(cMSG &m) { return ForAllFiles(&_DelFromLo,m); } int DeleteAttach(cMSG &m) { return ForAllFiles(&_DeleteAttach,m); } int ChangePath(cMSG &m,char *Path) { int rc; strcpy(NewPath,Path); memset(NewSubj,0,73); if (strlen(NewPath) != 0 && NewPath[strlen(NewPath)-1] != PATHDELIMC) { strcat(NewPath,PATHDELIMS); } rc = ForAllFiles(&_ChangePath,m); if (!rc) { return FALSE; } if (NewSubj[0] != '\0') { NewSubj[strlen(NewSubj)-1]='\0'; } if (strlen(NewSubj) > 71) { Log.Level(LOGE) << "New subject too long. '" << NewSubj << "'" << EOL; return FALSE; } strncpy(m._Subject,NewSubj,72); return TRUE; } int GetAttSize(cMSG &m) { int rc; AttSize = 0; rc = ForAllFiles(&_AttToSize,m); if (!rc) { return -1; } return AttSize; } int MoveAttach(cMSG &m,char *Path) { int rc; strcpy(NewPath,Path); memset(NewSubj,0,73); if (strlen(NewPath) != 0 && NewPath[strlen(NewPath)-1] != PATHDELIMC) { strcat(NewPath,PATHDELIMS); } rc = ForAllFiles(&_ChangePath,m); if (!rc) { return FALSE; } if (NewSubj[0] != '\0') { NewSubj[strlen(NewSubj)-1]='\0'; } if (strlen(NewSubj) > 71) { Log.Level(LOGE) << "New subject too long. '" << NewSubj << "'" << EOL; return FALSE; } rc = ForAllFiles(&_MoveAttach,m); if (!rc) { return FALSE; } strncpy(m._Subject,NewSubj,72); return TRUE; } int CopyAttach(cMSG &m,char *Path) { int rc; strcpy(NewPath,Path); if (strlen(NewPath) != 0 && NewPath[strlen(NewPath)-1] != PATHDELIMC) { strcat(NewPath,PATHDELIMS); } rc = ForAllFiles(&_CopyAttach,m); if (!rc) { return FALSE; } return TRUE; } int AttachExists(cMSG &m) { return ForAllFiles(&_AttachExists,m); } // -------------------------------------------------------------------- int SetFileInbound(char *tmt) { IndBiList::ElemPtr sd; sd = ScanDirs.GetLast(); if (sd == NULL) { if (FileInbound != NULL) { yyerror("File inbound directory aready defined."); return (-1); } } else { if (sd->_FileInbound != NULL) { yyerror("File inbound directory for this scandir aready defined."); return (-1); } } if (strlen(tmt) == 0) { yyerror("Missed parameter: Inbound directory name."); return (-1); } if (!DirExists(tmt)) { yyerror("Unable to open file inbound directory."); return (-1); } if (sd == NULL) { FileInbound = (char *) malloc(strlen(tmt) + 2); CheckMem(FileInbound); strcpy(FileInbound,tmt); if (FileInbound[strlen(FileInbound)-1] != PATHDELIMC) { strcat(FileInbound,PATHDELIMS); } } else { sd->_FileInbound = (char *) malloc(strlen(tmt) + 2); CheckMem(sd->_FileInbound); strcpy(sd->_FileInbound,tmt); if (FileInbound[strlen(sd->_FileInbound)-1] != PATHDELIMC) { strcat(sd->_FileInbound,PATHDELIMS); } } return 0; } int SetSkipHiddenFiles(void) { if (SkipHiddenFiles) { yyerror("SkipHiddenFiles already set."); return (-1); } SkipHiddenFiles = TRUE; return (0); } // ---------------------------- END --------------------------------------