// --------------------------------------------------------------------
// 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 <sys/types.h>
#include <sys/stat.h>
#ifndef UNIX
#include <io.h>
#endif
#if defined (UNIX) || defined(__DJGPP__)
#include <unistd.h>
#endif
#if defined(__DJGPP__)
#include <dos.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#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 <windows.h>
#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<ScanDir>::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 --------------------------------------
syntax highlighted by Code2HTML, v. 0.9.1