This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/mbsebbs/filesub.c
2007-06-09 11:48:48 +00:00

1163 lines
28 KiB
C

/*****************************************************************************
*
* $Id$
* Purpose ...............: All the file sub functions.
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************/
#include "../config.h"
#include "../lib/mbselib.h"
#include "../lib/mbse.h"
#include "../lib/users.h"
#include "../lib/mbsedb.h"
#include "filesub.h"
#include "funcs.h"
#include "language.h"
#include "input.h"
#include "misc.h"
#include "timeout.h"
#include "exitinfo.h"
#include "change.h"
#include "term.h"
#include "ttyio.h"
extern pid_t mypid;
int arecno = 1; /* Area record number */
int Hcolor = 9; /* Color of area line in xxxScan() functions */
extern int rows;
/*
* Variables for file tagging
*/
int Tagnr;
_Tag Tagbuf[100];
/*
* Reset the tag ringbuffer.
*/
void InitTag()
{
int i;
Tagnr = 0;
for (i = 0; i < 100; i++) {
memset(&Tagbuf[i], 0, sizeof(_Tag));
}
}
/*
* Add a file in the tag ringbuffer.
*/
void SetTag(_Tag tag)
{
if (Tagnr < 99)
Tagnr++;
else
Tagnr = 1;
Tagbuf[Tagnr] = tag;
}
/*
* Get string, no newline afterwards.
*/
void GetstrD(char *sStr, int iMaxlen)
{
unsigned char ch = 0;
int iPos = 0;
strcpy(sStr, "");
alarm_on();
while (ch != 13) {
ch = Readkey();
if (((ch == 8) || (ch == KEY_DEL) || (ch == 127)) && (iPos > 0)) {
BackErase();
sStr[--iPos]='\0';
}
if (ch > 31 && ch < 127) {
if (iPos <= iMaxlen) {
iPos++;
snprintf(sStr + strlen(sStr), 5, "%c", ch);
PUTCHAR(ch);
} else
PUTCHAR(7);
}
}
}
/*
* Open the fareas.data file for read or R/W and read the headerrecord.
* The filepointer is at the start of the first record.
*/
FILE *OpenFareas(int Write)
{
FILE *pAreas;
char *FileArea;
FileArea = calloc(PATH_MAX, sizeof(char));
snprintf(FileArea, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if (Write)
pAreas = fopen(FileArea, "r+");
else
pAreas = fopen(FileArea, "r");
if (pAreas == NULL) {
WriteError("$Can't open FileBase %s", FileArea);
/* FATAL: Unable to open areas database */
pout(LIGHTRED, BLACK, (char *) Language(243));
Enter(2);
sleep(2);
} else
fread(&areahdr, sizeof(areahdr), 1, pAreas);
free(FileArea);
return pAreas;
}
/*
* Pageheader for filelistings
*/
void Header()
{
char temp[81];
pout(RED, LIGHTGRAY, (char *)" Area ");
snprintf(temp, 81, "%-5d ", iAreaNumber);
pout(RED, LIGHTGRAY, temp);
snprintf(temp, 81, "%-65s", sAreaDesc);
pout(BLUE, LIGHTGRAY, temp);
Enter(1);
colour(WHITE, BLACK);
PUTSTR(chartran(fLine_str(79)));
iLineCount++;
}
/*
* Searchheader for areas during xxxxScan().
*/
void Sheader()
{
char temp[81];
PUTCHAR('\r');
snprintf(temp, 81, " %-4d", arecno);
pout(Hcolor, BLACK, temp);
pout(LIGHTBLUE, BLACK, (char *)" ... ");
snprintf(temp, 81, "%-44s", area.Name);
pout(Hcolor, BLACK, temp);
if (Hcolor < WHITE)
Hcolor++;
else
Hcolor = LIGHTBLUE;
}
/*
* Blank current line without newline.
*/
void Blanker(int count)
{
int i;
for (i = 0; i < count; i++)
PUTCHAR('\b');
for (i = 0; i < count; i++)
PUTCHAR(' ');
PUTCHAR('\r');
}
/*
* Mark one or more files for download by putting them into the "taglist"
* in the users homedirectory. Check against dupe tags.
*/
void Mark()
{
char *temp;
FILE *fp;
int i, Found, Count, Size;
temp = calloc(81, sizeof(char));
/*
* First count the already tagged files.
*/
Count = Size = 0;
if ((fp = fopen("taglist", "r")) != NULL) {
while (fread(&Tag, sizeof(Tag), 1, fp) == 1) {
if (Tag.Active) {
Count++;
Size += (Tag.Size / 1024);
}
}
fclose(fp);
}
/* Marked: */
snprintf(temp, 81, "%s%d, %dK; ", (char *) Language(360), Count, Size);
pout(CFG.HiliteF, CFG.HiliteB, temp);
/* Mark file number of press <Enter> to stop */
PUTSTR((char *) Language(7));
colour(CFG.InputColourF, CFG.InputColourB);
GetstrD(temp, 10);
Blanker(strlen(Language(7)) + strlen(temp));
if (strlen(temp) == 0) {
free(temp);
return;
}
i = atoi(temp);
if ((i > 0) && (i < 100)) {
if ((Tagbuf[i].Area) && (strlen(Tagbuf[i].LFile))) {
if (Access(exitinfo.Security, area.DLSec)) {
if ((fp = fopen("taglist", "a+")) != NULL) {
fseek(fp, 0, SEEK_SET);
Found = FALSE;
while (fread(&Tag, sizeof(Tag), 1, fp) == 1)
if ((Tag.Area == Tagbuf[i].Area) && (strcmp(Tag.LFile, Tagbuf[i].LFile) == 0)) {
Found = TRUE;
Syslog('b', "Tagbuf[i].File already tagged");
}
if (!Found) {
memset(&Tag, 0, sizeof(Tag));
Tag = Tagbuf[i];
Tag.Active = TRUE;
fwrite(&Tag, sizeof(Tag), 1, fp);
Syslog('+', "Tagged file %s from area %d", Tag.LFile, Tag.Area);
}
fclose(fp);
}
} else {
/* You do not have enough access to download from this area. */
pout(LIGHTRED, BLACK, (char *) Language(244));
sleep(3);
Blanker(strlen(Language(244)));
}
}
}
free(temp);
}
/*
* More prompt, returns 1 if user decides not to look any further.
*/
int iLC(int Lines)
{
int x, z;
x = strlen(Language(131));
iLineCount += Lines;
if ((iLineCount >= rows) && (iLineCount < 1000)) {
iLineCount = 1;
while (TRUE) {
/* More (Y/n/=) M=Mark */
pout(CFG.MoreF, CFG.MoreB, (char *) Language(131));
alarm_on();
z = toupper(Readkey());
Blanker(x);
if (z == Keystroke(131, 1)) {
Enter(1);
return 1;
}
if (z == Keystroke(131, 2)) {
iLineCount = 9000;
return 0;
}
if ((z == Keystroke(131, 0)) || (z == '\r') || (z == '\n')) {
return 0;
}
if (z == Keystroke(131, 3)) {
Mark();
}
}
}
return 0;
}
/*
* Show one file, return 1 if user wants to stop, 0 to show next file.
*/
int ShowOneFile()
{
int y, z, fg, bg;
char temp[81];
if (!fdb.Deleted) {
snprintf(temp, 81, " %02d ", Tagnr);
pout(LIGHTGRAY, BLACK, temp);
snprintf(temp, 81, "[%4d] ", fdb.TimesDL);
pout(LIGHTRED, BLACK, temp);
snprintf(temp, 81, "%s", fdb.LName);
pout(CFG.FilenameF, CFG.FilenameB, temp);
Enter(1);
if (iLC(1) == 1)
return 1;
snprintf(temp, 81, " %-10s ", StrDateDMY(fdb.UploadDate));
pout(CFG.FiledateF, CFG.FiledateB, temp);
snprintf(temp, 81, "%10u bytes ", (int)(fdb.Size));
pout(CFG.FilesizeF, CFG.FilesizeB, temp);
// snprintf(temp, 81, "%-12s", fdb.Name);
// pout(CFG.FilenameF, CFG.FilenameB, temp);
// snprintf(temp, 81, "%10u ", (int)(fdb.Size));
// pout(CFG.FilesizeF, CFG.FilesizeB, temp);
// snprintf(temp, 81, "%-10s ", StrDateDMY(fdb.UploadDate));
// pout(CFG.FiledateF, CFG.FiledateB, temp);
// snprintf(temp, 81, "[%4d] ", fdb.TimesDL);
// pout(LIGHTRED, BLACK, temp);
// if ((strcmp(fdb.Uploader, "")) == 0)
// strcpy(fdb.Uploader, "SysOp");
// snprintf(temp, 81, "%s%s", (char *) Language(238), fdb.Uploader);
// pout(CFG.HiliteF, CFG.HiliteB, temp);
Enter(1);
if (iLC(1) == 1)
return 1;
for (z = 0; z < 25; z++) {
if ((y = strlen(fdb.Desc[z])) > 1) {
if ((fdb.Desc[z][0] == '@') && (fdb.Desc[z][1] == 'X')) {
/*
* Color formatted description lines.
*/
if (fdb.Desc[z][3] > '9')
fg = (int)fdb.Desc[z][3] - 55;
else
fg = (int)fdb.Desc[z][3] - 48;
bg = (int)fdb.Desc[z][2] - 48;
colour(fg, bg);
PUTSTR((char *)" ");
PUTSTR(chartran(fdb.Desc[z]+4));
} else {
colour(CFG.FiledescF, CFG.FiledescB);
PUTSTR((char *)" ");
PUTSTR(chartran(fdb.Desc[z]));
}
Enter(1);
if (iLC(1) == 1)
return 1;
}
}
}
return 0;
}
int CheckBytesAvailable(int CostSize)
{
char temp[81];
if (LIMIT.DownK) {
if ((exitinfo.DownloadKToday <= 0) || ((CostSize / 1024) > exitinfo.DownloadKToday)) {
/* You do not have enough bytes to download \" */
pout(LIGHTRED, BLACK, (char *) Language(252));
Enter(1);
Syslog('+', "Not enough bytes to download %ld", CostSize);
/* You must upload before you can download. */
pout(LIGHTRED, BLACK, (char *) Language(253));
Enter(2);
/* Kilobytes currently available: */
snprintf(temp, 81, "%s%u Kbytes.", (char *) Language(254), exitinfo.DownloadKToday);
pout(YELLOW, BLACK, temp);
Enter(2);
Pause();
return FALSE;
}
}
return TRUE;
}
/*
* Change back to users homedir.
*/
void Home()
{
char *temp;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/%s", CFG.bbs_usersdir, exitinfo.Name);
chdir(temp);
free(temp);
}
/*
* Scan a .COM or .EXE file in users upload directory.
*/
int ScanDirect(char *fn)
{
FILE *fp, *lp;
int err, Found = FALSE;
char *temp, *temp1, *stdlog, *errlog, buf[256], msg[81];
temp = calloc(PATH_MAX, sizeof(char));
temp1 = calloc(PATH_MAX, sizeof(char));
stdlog = calloc(PATH_MAX, sizeof(char));
errlog = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/%s/upl/%s", CFG.bbs_usersdir, exitinfo.Name, fn);
snprintf(temp1, PATH_MAX, "%s/etc/virscan.data", getenv("MBSE_ROOT"));
snprintf(stdlog, PATH_MAX, "%s/tmp/stdlog%d", getenv("MBSE_ROOT"), mypid);
snprintf(errlog, PATH_MAX, "%s/tmp/errlog%d", getenv("MBSE_ROOT"), mypid);
if ((fp = fopen(temp1, "r")) != NULL) {
fread(&virscanhdr, sizeof(virscanhdr), 1, fp);
while (fread(&virscan, virscanhdr.recsize, 1, fp) == 1) {
if (virscan.available && (file_exist(virscan.scanner, X_OK) == 0)) {
/* Scanning */ /* with */
snprintf(msg, 81, "%s %s %s %s ", (char *) Language(132), fn, (char *) Language(133), virscan.comment);
pout(CFG.TextColourF, CFG.TextColourB, msg);
Altime(3600);
err = execute_str(virscan.scanner, virscan.options, temp, (char *)"/dev/null", stdlog, errlog);
if (file_size(stdlog)) {
if ((lp = fopen(stdlog, "r"))) {
while (fgets(buf, sizeof(buf) -1, lp)) {
Striplf(buf);
Syslog('+', "stdout: \"%s\"", printable(buf, 0));
}
fclose(lp);
}
}
if (file_size(errlog)) {
if ((lp = fopen(errlog, "r"))) {
while (fgets(buf, sizeof(buf) -1, lp)) {
Striplf(buf);
Syslog('+', "stderr: \"%s\"", printable(buf, 0));
}
fclose(lp);
}
}
unlink(stdlog);
unlink(errlog);
if (err != virscan.error) {
WriteError("VIRUS ALERT: Result %d (%s)", err, virscan.comment);
/* Possible VIRUS found! */
snprintf(msg, 81, "%s", (char *) Language(199));
pout(CFG.HiliteF, CFG.HiliteB, msg);
Found = TRUE;
} else {
/* Ok */
snprintf(msg, 81, "%s", (char *) Language(200));
PUTSTR(msg);
}
Enter(1);
Altime(0);
Nopper();
}
}
fclose(fp);
}
free(temp);
free(temp1);
free(stdlog);
free(errlog);
return Found;
}
/*
* Scan archive using users ./tmp directory.
* Return codes:
* 0 - All seems well
* 1 - Error unpacking archive
* 2 - Possible virus found
* 3 - Not a known archive format.
*/
int ScanArchive(char *fn, char *ftype)
{
FILE *fp, *lp;
int err = 0, Found = FALSE;
char *temp, *stdlog, *errlog, buf[256], msg[81];
char *cwd = NULL;
/*
* First search for the right archiver program
*/
temp = calloc(PATH_MAX, sizeof(char));
stdlog = calloc(PATH_MAX, sizeof(char));
errlog = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/archiver.data", getenv("MBSE_ROOT"));
snprintf(stdlog, PATH_MAX, "%s/tmp/stdlog%d", getenv("MBSE_ROOT"), mypid);
snprintf(errlog, PATH_MAX, "%s/tmp/errlog%d", getenv("MBSE_ROOT"), mypid);
if ((fp = fopen(temp, "r")) == NULL) {
free(temp);
return 3;
}
fread(&archiverhdr, sizeof(archiverhdr), 1, fp);
while (fread(&archiver, archiverhdr.recsize, 1, fp) == 1) {
if ((strcmp(ftype, archiver.name) == 0) && (archiver.available)) {
break;
}
}
fclose(fp);
if ((strcmp(ftype, archiver.name)) || (!archiver.available)) {
free(temp);
return 3;
}
cwd = getcwd(cwd, 80);
snprintf(temp, PATH_MAX, "%s/%s/tmp", CFG.bbs_usersdir, exitinfo.Name);
if (chdir(temp)) {
WriteError("$Can't chdir(%s)", temp);
free(temp);
return 1;
}
/* Unpacking archive */
snprintf(msg, 81, "%s %s ", (char *) Language(201), fn);
pout(CFG.TextColourF, CFG.TextColourB, msg);
if (!strlen(archiver.funarc)) {
WriteError("No unarc command available");
} else {
snprintf(temp, PATH_MAX, "%s/%s/upl/%s", CFG.bbs_usersdir, exitinfo.Name, fn);
if (execute_str(archiver.funarc, temp, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")) {
WriteError("$Failed %s %s", archiver.funarc, temp);
execute_pth((char *)"rm", (char *)"-r -f ./*", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
chdir(cwd);
free(cwd);
/* ERROR */
pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(217));
Enter(1);
return 1;
}
}
/* Ok */
PUTSTR((char *) Language(200));
Enter(1);
snprintf(temp, PATH_MAX, "%s/etc/virscan.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) != NULL) {
fread(&virscanhdr, sizeof(virscanhdr), 1, fp);
while (fread(&virscan, virscanhdr.recsize, 1, fp) == 1) {
if (virscan.available && (file_exist(virscan.scanner, X_OK) == 0)) {
/* Scanning */ /* with */
snprintf(msg, 81, "%s %s %s %s ", (char *) Language(132), fn, (char *) Language(133), virscan.comment);
pout(CFG.TextColourF, CFG.TextColourB, msg);
Altime(3600);
err = execute_str(virscan.scanner, virscan.options, (char *)NULL, (char *)"/dev/null", stdlog, errlog);
if (file_size(stdlog)) {
if ((lp = fopen(stdlog, "r"))) {
while (fgets(buf, sizeof(buf) -1, lp)) {
Striplf(buf);
Syslog('+', "stdout: \"%s\"", printable(buf, 0));
}
fclose(lp);
}
}
if (file_size(errlog)) {
if ((lp = fopen(errlog, "r"))) {
while (fgets(buf, sizeof(buf) -1, lp)) {
Striplf(buf);
Syslog('+', "stderr: \"%s\"", printable(buf, 0));
}
fclose(lp);
}
}
unlink(stdlog);
unlink(errlog);
if (err != virscan.error) {
WriteError("VIRUS ALERT: Result %d (%s)", err, virscan.comment);
/* Possible VIRUS found! */
pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(199));
Found = TRUE;
} else {
/* Ok */
PUTSTR((char *) Language(200));
}
Enter(1);
Altime(0);
Nopper();
}
}
fclose(fp);
}
execute_pth((char *)"rm", (char *)"-r -f ./*", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
chdir(cwd);
free(cwd);
free(temp);
free(stdlog);
free(errlog);
if (Found)
return 2;
else
return 0;
}
/*
* Try to find out the type of uploaded file.
*/
char *GetFileType(char *fn)
{
unsigned char buf[8], dbuf[80];
FILE *fp;
int i;
if ((fp = fopen(fn, "r")) == NULL) {
WriteError("$Can't open file %s", fn);
return NULL;
}
if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf)) {
WriteError("$Can't read head of file %s", fn);
return NULL;
}
fclose(fp);
dbuf[0] = '\0';
for (i = 0; i < sizeof(buf); i++)
if ((buf[i] >= ' ') && (buf[i] <= 127))
snprintf((char*)dbuf+strlen(dbuf), 80, " %c", buf[i]);
else
snprintf((char*)dbuf+strlen(dbuf), 80, " %02x", buf[i]);
/*
* Various expected uploads. Not that the standard MS-DOS archivers
* must return the exact format, ie "ZIP" for PKZIP. These strings
* are tested against the archivers database. Others that aren't
* compressed files are not important, they just pop up in your
* logfiles.
*/
if (memcmp(buf, "PK\003\004", 4) == 0) return (char *)"ZIP";
if (*buf == 0x1a) return (char *)"ARC";
if (memcmp(buf+2, "-l", 2) == 0) return (char *)"LHA";
if (memcmp(buf, "ZOO", 3) == 0) return (char *)"ZOO";
if (memcmp(buf, "`\352", 2) == 0) return (char *)"ARJ";
if (memcmp(buf, "Rar!", 4) == 0) return (char *)"RAR";
if (memcmp(buf, "HA", 2) == 0) return (char *)"HA";
if (memcmp(buf, "MZ", 2) == 0) return (char *)"EXE";
if (memcmp(buf, "\000\000\001\263", 4) == 0) return (char *)"MPEG";
if (memcmp(buf, "MOVI", 4) == 0) return (char *)"MOVI";
if (memcmp(buf, "\007\007\007", 3) == 0) return (char *)"CPIO";
if (memcmp(buf, "\351,\001JAM", 6) == 0) return (char *)"JAM";
if (memcmp(buf, "SQSH", 4) == 0) return (char *)"SQSH";
if (memcmp(buf, "UC2\0x1a", 4) == 0) return (char *)"UC2";
if (memcmp(buf, ".snd", 4) == 0) return (char *)"SND";
if (memcmp(buf, "MThd", 4) == 0) return (char *)"MID";
if (memcmp(buf, "RIFF", 4) == 0) return (char *)"WAV";
if (memcmp(buf, "EMOD", 4) == 0) return (char *)"MOD";
if (memcmp(buf, "MTM", 3) == 0) return (char *)"MTM";
if (memcmp(buf, "#!/bin/", 7) == 0) return (char *)"UNIX script";
if (memcmp(buf, "\037\235", 2) == 0) return (char *)"Compressed data";
if (memcmp(buf, "\037\213", 2) == 0) return (char *)"GZIP";
if (memcmp(buf, "\177ELF", 4) == 0) return (char *)"ELF";
if (memcmp(buf, "%!", 2) == 0) return (char *)"PostScript";
if (memcmp(buf, "GIF8", 4) == 0) return (char *)"GIF";
if (memcmp(buf, "\377\330\377\340", 4) == 0) return (char *)"JPEG";
if (memcmp(buf, "\377\330\377\356", 4) == 0) return (char *)"JPG";
if (memcmp(buf, "BM", 2) == 0) return (char *)"Bitmap";
if (memcmp(buf, "%PDF", 4) == 0) return (char *)"PDF";
if (memcmp(buf, "THNL", 4) == 0) return (char *)"ThumbNail";
if ((memcmp(buf, "<html>", 6) == 0) ||
(memcmp(buf, "<HTML>", 6) == 0)) return (char *)"HTML";
if (memcmp(buf, "MSCF", 4) == 0) return (char *)"CAB";
if (memcmp(buf, "BZ", 2) == 0) return (char *)"BZIP";
/*
* .COM formats. Should cover about 2/3 of COM files.
*/
if ((*buf == 0xe9) || (*buf == 0x8c) ||
(*buf == 0xeb) || (*buf == 0xb8)) return (char *)"COM";
return NULL;
}
/*
* Import file in area. Returns TRUE if successfull.
*/
int ImportFile(char *fn, int Area, int fileid, off_t Size)
{
char *temp, *temp1, msg[81];
temp = calloc(PATH_MAX, sizeof(char));
temp1 = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/%s", area.Path, basename(fn));
snprintf(temp1, PATH_MAX, "%s", fn);
if ((file_mv(temp1, temp))) {
WriteError("$Can't move %s to %s", fn, area.Path);
} else {
chmod(temp, 0664);
if (Addfile(basename(fn), Area, fileid)) {
ReadExitinfo();
/*
* If Size is equal to Zero, don't increase file counters else
* Increase file counters if any other size
*/
if (Size) {
exitinfo.Uploads++;
exitinfo.UploadK += (Size / 1024);
exitinfo.UploadKToday += (Size / 1024);
Syslog('b', "Uploads %d, Kb %d, Kb today %d", exitinfo.Uploads, exitinfo.UploadK, exitinfo.UploadKToday);
/* You have */ /* extra download KBytes. */
snprintf(msg, 81, "%s %d %s", (char *) Language(249), (int)(Size / 1024), (char *) Language(250));
PUTSTR(msg);
Enter(1);
exitinfo.DownloadKToday += (Size / 1024);
Syslog('b', "DownloadKToday %d", exitinfo.DownloadKToday);
}
WriteExitinfo();
free(temp);
free(temp1);
return TRUE;
}
}
free(temp);
free(temp1);
return FALSE;
}
/*
* Add file to the FileDataBase. If fileid is true, then try to
* get the filedescription from FILE_ID.DIZ if it is in the
* archive, else the user must supply the description.
* Returns TRUE is successfull.
*/
int Addfile(char *File, int AreaNum, int fileid)
{
FILE *id, *pPrivate;
int err = 1, iDesc = 1, iPrivate = FALSE, GotId = FALSE, lines, i, j;
char *Filename, *temp1, *idname = NULL, *Desc[26], *lname, temp[PATH_MAX], msg[81];
struct stat statfile;
struct _fdbarea *fdb_area = NULL;
Filename = calloc(PATH_MAX, sizeof(char));
temp1 = calloc(PATH_MAX, sizeof(char));
lname = calloc(PATH_MAX, sizeof(char));
snprintf(Filename, PATH_MAX, "%s/%s", area.Path, File);
if ((fdb_area = mbsedb_OpenFDB(AreaNum, 30))) {
/*
* Do a physical check of file to see if it exists
* if it fails it will return a zero which will not
* increase his uploads stats
*/
if (stat(Filename, &statfile) != 0) {
Enter(1);
colour(10, 0);
/* Upload was unsuccessful for: */
snprintf(msg, 81, "%s%s", (char *) Language(284), File);
pout(LIGHTGREEN, BLACK, msg);
Enter(2);
mbsedb_CloseFDB(fdb_area);
free(Filename);
free(temp1);
free(lname);
return FALSE;
}
memset(&fdb, 0, fdbhdr.recsize);
strncpy(fdb.LName, File, 80); /* LFN, currently real file */
strcpy(temp1, File);
name_mangle(temp1);
strncpy(fdb.Name, temp1, 12); /* 8.3 name */
fdb.Size = (int)(statfile.st_size);
fdb.FileDate = statfile.st_mtime;
fdb.Crc32 = file_crc(Filename, TRUE);
strncpy(fdb.Uploader, exitinfo.sUserName, 35);
fdb.UploadDate = time(NULL);
/*
* Create the symlink is done in the real directory
*/
if (getcwd(lname, PATH_MAX-1)) {
chdir(area.Path);
if (strcmp(fdb.Name, fdb.LName)) {
/*
* Rename the file first to the 8.3 name, this is the
* standard way to store files in the filebase.
*/
rename(fdb.LName, fdb.Name);
/*
* Then make a symlink to the 8.3 name
*/
if (symlink(fdb.Name, fdb.LName)) {
WriteError("$Can't create link %s to %s", fdb.Name, fdb.LName);
}
}
chdir(lname);
}
free(lname);
if (area.PwdUP) {
Enter(1);
/* Do you want to password protect your upload ? [y/N]: */
pout(LIGHTBLUE, BLACK, (char *) Language(285));
if (toupper(Readkey()) == Keystroke(285, 0)) {
Enter(1);
/* REMEMBER: Passwords are "CaSe SeNsITiVe!" */
pout(LIGHTGREEN, BLACK, (char *) Language(286));
Enter(1);
/* Password: */
pout(YELLOW, BLACK, (char *) Language(8));
GetstrC(fdb.Password, 20);
}
}
if (fileid && strlen(archiver.iunarc)) {
/*
* The right unarchiver is still in memory,
* get the FILE_ID.DIZ if it exists.
*/
snprintf(temp, PATH_MAX, "%s/%s", area.Path, File);
if ((err = execute_str(archiver.iunarc, temp, (char *)"FILE_ID.DIZ", (char *)"/dev/null",
(char *)"/dev/null", (char *)"/dev/null"))) {
if ((err = execute_str(archiver.iunarc, temp, (char *)"file_id.diz", (char *)"/dev/null",
(char *)"/dev/null", (char *)"/dev/null"))) {
Syslog('+', "No FILE_ID.DIZ found in %s", File);
} else {
idname = xstrcpy((char *)"file_id.diz");
}
} else {
idname = xstrcpy((char *)"FILE_ID.DIZ");
}
if (!err) {
Syslog('+', "Found %s", idname);
GotId = TRUE;
}
}
if (GotId) {
lines = 0;
if ((id = fopen(idname, "r")) != NULL) {
/*
* Import FILE_ID.DIZ, format to max. 25 * lines, 48 chars width.
*/
while (((fgets(temp1, PATH_MAX -1, id)) != NULL) && (lines < 25)) {
Striplf(temp1);
if (strlen(temp1) > 51) {
/*
* Malformed FILE_ID.DIZ
*/
GotId = FALSE;
for (i = 0; i < 25; i++)
fdb.Desc[i][0] = '\0';
lines = 0;
Syslog('!', "Trashing illegal formatted FILE_ID.DIZ");
break;
}
if (strlen(temp1) > 0) {
j = 0;
for (i = 0; i < strlen(temp1); i++) {
if (isprint(temp1[i])) {
fdb.Desc[lines][j] = temp1[i];
j++;
if (j > 47)
break;
}
}
/*
* Remove trailing spaces
*/
while (j && isspace(fdb.Desc[lines][j-1]))
j--;
fdb.Desc[lines][j] = '\0';
lines++;
}
}
fclose(id);
} else {
GotId = FALSE;
}
unlink(idname);
if (GotId) {
/*
* Strip empty FILE_ID.DIZ lines at the end
*/
while ((strlen(fdb.Desc[lines-1]) == 0) && (lines)) {
fdb.Desc[lines-1][0] = '\0';
lines--;
}
if (lines) {
Syslog('+', "Using %d FILE_ID.DIZ lines for description", lines);
/* Found FILE_ID.DIZ in */
snprintf(msg, 81, "%s %s", (char *) Language(257), File);
pout(CFG.TextColourF, CFG.TextColourB, msg);
Enter(1);
} else {
Syslog('!', "No FILE_ID.DIZ lines left to use");
GotId = FALSE;
}
}
}
if (!GotId) {
/*
* Ask the user for a description.
*/
for (i = 0; i < 26; i++)
*(Desc + i) = (char *) calloc(49, sizeof(char));
Enter(1);
/* Please enter description of file */
snprintf(msg, 81, "%s %s", (char *) Language(287), File);
pout(LIGHTRED, BLACK, msg);
Enter(2);
while (TRUE) {
snprintf(msg, 81, "%2d> ", iDesc);
pout(LIGHTGREEN, BLACK, msg);
colour(CFG.InputColourF, CFG.InputColourB);
GetstrC(*(Desc + iDesc), 47);
if ((strcmp(*(Desc + iDesc), "")) == 0)
break;
iDesc++;
if (iDesc >= 26)
break;
}
for (i = 1; i < iDesc; i++)
strcpy(fdb.Desc[i - 1], Desc[i]);
for (i = 0; i < 26; i++)
free(Desc[i]);
}
/*
* Log upload before adding to the filebase, after insert the fdb record
* is overwritten.
*/
snprintf(temp, PATH_MAX, "%s/log/uploads.log", getenv("MBSE_ROOT"));
if ((pPrivate = fopen(temp, "a+")) == NULL)
WriteError("$Can't open %s", temp);
else {
iPrivate = TRUE;
fprintf(pPrivate, "****************************************************");
fprintf(pPrivate, "\nUser : %s", fdb.Uploader);
fprintf(pPrivate, "\nFile : %s (%s)", fdb.LName, fdb.Name);
fprintf(pPrivate, "\nSize : %u", (int)(fdb.Size));
fprintf(pPrivate, "\nUpload Date : %s\n\n", StrDateDMY(fdb.UploadDate));
for (i = 0; i < iDesc - 1; i++)
fprintf(pPrivate, "%2d: %s\n", i, fdb.Desc[i]);
fclose(pPrivate);
}
mbsedb_InsertFDB(fdb_area, fdb, area.AddAlpha);
mbsedb_CloseFDB(fdb_area);
Enter(1);
/* Your upload time has been returned to you. Thank you for your upload! */
pout(LIGHTGREEN, BLACK, (char *) Language(288));
Enter(1);
}
free(Filename);
free(temp1);
return TRUE;
}
/*
* Set file area number, set global area description and path.
*/
void SetFileArea(unsigned int AreaNum)
{
FILE *pArea;
int offset;
memset(&area, 0, sizeof(area));
if ((pArea = OpenFareas(FALSE)) == NULL)
return;
offset = areahdr.hdrsize + ((AreaNum - 1) * areahdr.recsize);
if (fseek(pArea, offset, 0) != 0) {
WriteError("$Seek error in fareas.data, area %ld", AreaNum);
return;
}
fread(&area, areahdr.recsize, 1, pArea);
strcpy(sAreaDesc, area.Name);
strcpy(sAreaPath, area.Path);
iAreaNumber = AreaNum;
fclose(pArea);
}
/*
* Return size in bytes of all files in the users wrk directory.
*/
unsigned int Quota()
{
DIR *dirp;
char *FileName, *temp;
unsigned int Bytes = 0;
struct dirent *dp;
struct stat statfile;
FileName = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/%s/wrk", CFG.bbs_usersdir, exitinfo.Name);
if ((dirp = opendir(temp)) == NULL) {
WriteError("$Can't open dir %s", temp);
} else {
while ((dp = readdir(dirp)) != NULL) {
snprintf(FileName, PATH_MAX, "%s/%s", temp, dp->d_name);
if (*(dp->d_name) != '.')
if (stat(FileName, &statfile) == 0)
Bytes += statfile.st_size;
}
closedir(dirp);
}
free(FileName);
free(temp);
return Bytes;
}
void ImportHome(char *fn)
{
char *temp1, *temp2;
temp1 = calloc(PATH_MAX, sizeof(char));
temp2 = calloc(PATH_MAX, sizeof(char));
snprintf(temp1, PATH_MAX, "%s/%s/wrk/%s", CFG.bbs_usersdir, exitinfo.Name, fn);
snprintf(temp2, PATH_MAX, "%s/%s/upl/%s", CFG.bbs_usersdir, exitinfo.Name, fn);
Syslog('+', "Move %s to home, result %d", fn, file_mv(temp2, temp1));
free(temp1);
free(temp2);
}