Пример #1
0
void user(void)
{
    FILE	*pUsrConfig, *pLimits;
    int		i, x, FoundName = FALSE, iFoundLimit = FALSE, IsNew = FALSE, logins = 0, Start;
    int		l1, l2;
    char	*token, temp[PATH_MAX], temp1[84], UserName[37], buf[128], *fullname;
    time_t	LastLogin;
    struct stat st;

    grecno = 0;
    Syslog('+', "Unixmode login: %s", sUnixName);

    snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("FTND_ROOT"));
    if ((pUsrConfig = fopen(temp,"r+")) == NULL) {
	/*
	 * This should not happen.
	 */
	WriteError("$Can't open %s", temp);
	PUTSTR((char *)"Can't open userfile, run \"newuser\" first");
	Enter(1);
	ExitClient(FTNERR_OK);
    }

    fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig);
    while (fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig) == 1) {
	if (strcmp(usrconfig.Name, sUnixName) == 0) {
	    FoundName = TRUE;
	    break;
	} else
	    grecno++;
    }
							
    if (!FoundName) {
	fclose(pUsrConfig);
	snprintf(temp, PATH_MAX, "Unknown username: %s\r\n", sUnixName);
	PUTSTR(temp);
	/* FATAL ERROR: You are not in the BBS users file.*/
	snprintf(temp, PATH_MAX, "%s\r\n", (char *) Language(389));
	PUTSTR(temp);
	/* Please run 'newuser' to create an account */
	snprintf(temp, PATH_MAX, "%s\r\n", (char *) Language(390));
	PUTSTR(temp);
	Syslog('?', "FATAL: Could not find user in BBS users file.");
	Syslog('?', "       and system is using unix accounts\n");
	Free_Language();
	ExitClient(FTNERR_OK);
    }

    /*
     * Copy username, split first and lastname.
     */
    strncpy(UserName, usrconfig.sUserName, sizeof(UserName)-1);
    if ((strchr(UserName,' ') == NULL) && !CFG.iOneName) {
	token = strtok(UserName, " ");
  	strncpy(FirstName, token, sizeof(FirstName)-1);
  	token = strtok(NULL, "\0");
	i = strlen(token);
	for (x = 2; x < i; x++) {
	    if (token[x] == ' ')
		token[x] = '\0';
	}
	strncpy(LastName, token, sizeof(LastName)-1);
    } else
	strncpy(FirstName, UserName, sizeof(FirstName)-1);
    strncpy(UserName, usrconfig.sUserName, sizeof(UserName)-1);
    Syslog('+', "%s On-Line from \"%s\", node %d", UserName, ttyinfo.comment, iNode);
    IsDoing("Just Logged In");

    /*
     * Check some essential files, create them if they don't exist.
     */
    ChkFiles();

    /*
     * Setup users favourite language.
     */
    utf8 = (usrconfig.Charset == FTNC_UTF8);
    Set_Language(usrconfig.iLanguage);
    Free_Language();
    InitLanguage();

    /*
     * User logged in, tell it to the server. Check if a location is
     * set, if Ask User location for new users is off, this field is
     * empty but we have to send something to the server.
     */
    if (strlen(usrconfig.sLocation))
	UserCity(mypid, usrconfig.Name, usrconfig.sLocation);
    else
	UserCity(mypid, usrconfig.Name, (char *)"N/A");

    /*
     * Count simultaneous logins
     */
    Start = TRUE;
    while (TRUE) {
	if (Start)
	    snprintf(buf, 128, "GMON:1,1;");
	else
	    snprintf(buf, 128, "GMON:1,0;");
	Start = FALSE;
	if (socket_send(buf) == 0) {
	    strcpy(buf, socket_receive());
	    if (strncmp(buf, "100:0;", 6) == 0)
		break;  /* No more data */
	    if (strstr(buf, "ftnbbs")) {
		/*
		 * Only ftnbbs is wanted
		 */
		strtok(buf, ",");				    /* response */
		strtok(NULL, ",");				    /* pid	*/
		strtok(NULL, ",");				    /* tty	*/
		fullname = xstrcpy(cldecode(strtok(NULL, ",")));    /* username */
		if (strcmp(fullname, usrconfig.Name) == 0) {
		    logins++;
		}
		free(fullname);
	    }
	}
    }
    if (CFG.max_logins && (logins > CFG.max_logins)) {
	Syslog('+', "User logins %d, allowed %d, disconnecting", logins, CFG.max_logins);
	colour(LIGHTRED, BLACK);
	snprintf(temp, PATH_MAX, "%s %d %s\r\n", (char *) Language(18), CFG.max_logins, (char *) Language(19));
	PUTSTR(temp);
	Quick_Bye(FTNERR_INIT_ERROR);
    }
    
    /*
     * Set last file and message area so these numbers are saved when
     * the user hangs up or is logged off before het gets to the main
     * menu. Later in this function the areas are set permanent.
     */
    iAreaNumber = usrconfig.iLastFileArea;
    iMsgAreaNumber = usrconfig.iLastMsgArea;

    /*
     * See if this user is the Sysop.
     */
    strcpy(temp, UserName);
    strcpy(temp1, CFG.sysop_name);
    if ((strcasecmp(CFG.sysop_name, UserName)) == 0) {
	/*
	 * If login name is sysop, set SYSOP true 
	 */
	SYSOP = TRUE;
	Syslog('+', "Sysop is online");
    }

    /*
     * Is this a new user?
     */
    if (usrconfig.iTotalCalls == 0)
	IsNew = TRUE;

    /*
     * Pause after logo screen.
     */
    alarm_on();
    Pause();

    if (usrconfig.Archiver[0] == '\0') {
	usrconfig.Archiver[0] = 'Z';
	usrconfig.Archiver[1] = 'I';
	usrconfig.Archiver[2] = 'P';
	Syslog('+', "Setup default archiver ZIP");
    }

    /*
     * Check users date format. We do it strict as we
     * need this to be good for several other purposes.
     * If it is correct, the users age is set in UserAge
     */
    if (!Test_DOB(usrconfig.sDateOfBirth)) {
	Syslog('!', "Error in Date of Birth");
	Chg_DOB();
	strcpy(usrconfig.sDateOfBirth, exitinfo.sDateOfBirth);
    }

    /*
     * Check to see if user must expire
     */
    snprintf(temp,PATH_MAX, "%s", (char *) GetDateDMY());
    SwapDate(temp, usrconfig.sExpiryDate);

    /* Convert Date1 & Date2 to longs for compare */
    l1 = atol(Date1);
    l2 = atol(Date2);

    if (l1 >= l2 && l2 != 0) {
	/* 
	 * If Expiry Date is the same as today expire to 
	 * Expire Sec level
	 */
	usrconfig.Security = usrconfig.ExpirySec;
	Syslog('!', "User is expired, resetting level");
	/*
	 * Show texfile to user telling him about this.
	 */
	DisplayFile((char *)"expired");
    }

    free(Date1); 
    free(Date2);

    /* 
     * Copy limits.data into memory
     */
    snprintf(temp, PATH_MAX, "%s/etc/limits.data", getenv("FTND_ROOT"));

    if ((pLimits = fopen(temp,"rb")) == NULL) {
	WriteError("$Can't open %s", temp);
    } else {
	fread(&LIMIThdr, sizeof(LIMIThdr), 1, pLimits);

	while (fread(&LIMIT, sizeof(LIMIT), 1, pLimits) == 1) {
 	    if (LIMIT.Security == usrconfig.Security.level) {
		iFoundLimit = TRUE;
		break;
	    }
	}
	fclose(pLimits);
    }

    if (!iFoundLimit) {
	WriteError("Unknown Security Level in limits.data");
	usrconfig.iTimeLeft = 0; /* Could not find limit, so set to Zero */
	usrconfig.iTimeUsed = 0; /* Set to Zero as well  */
    } else {
	/*
	 * Give user new time limit everyday, also new users get a new limit.
	 */
	snprintf(temp,PATH_MAX, "%s", (char *) GetDateDMY());
	if (((strcmp(StrDateDMY(usrconfig.tLastLoginDate), temp)) != 0) || IsNew) {
	    /*
	     *  If no timelimit set give user 24 hours.
	     */
	    if (LIMIT.Time)
		usrconfig.iTimeLeft = LIMIT.Time;
	    else
		usrconfig.iTimeLeft = 86400;
	    usrconfig.iTimeUsed    = 0;          /* Set time used today to Zero       */
	    usrconfig.iConnectTime = 0;	     /* Set connect time to Zero          */

	    /*
	     * Give user new bytes and files every day if needed.
	     */
	    if (LIMIT.DownK) {
		usrconfig.DownloadKToday = LIMIT.DownK;
	    }
            if (LIMIT.DownF) {
                usrconfig.DownloadsToday = LIMIT.DownF;
            }
	}
    } /* End of else  */

    usrconfig.iConnectTime = 0;

    /* Copy Users Protocol into Memory */
    Set_Protocol(usrconfig.sProtocol);
    tlf(usrconfig.sProtocol);

    /* 
     * Set last login Date and Time, copy previous session
     * values in memory.
     */
    snprintf(LastLoginDate, 12, "%s", StrDateDMY(usrconfig.tLastLoginDate));
    snprintf(LastLoginTime, 9, "%s", StrTimeHMS(usrconfig.tLastLoginDate));
    LastLogin = usrconfig.tLastLoginDate;
    usrconfig.tLastLoginDate = ltime; /* Set current login to current date */
    usrconfig.iTotalCalls++;

    /*
     * Update user record.
     */
    if (fseek(pUsrConfig, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), 0) != 0) {
	WriteError("Can't seek in %s/etc/users.data", getenv("FTND_ROOT"));
    } else {
	fwrite(&usrconfig, sizeof(usrconfig), 1, pUsrConfig);
    }
    fclose(pUsrConfig);

    /*
     * Write users structure to tmp file in ~/home/unixname/exitinfo
     * A copy of the userrecord is also in the variable exitinfo.
     */
    if (! InitExitinfo())
	Good_Bye(FTNERR_INIT_ERROR);

    /*
     * If user has not set a preferred character set, force this
     */
    if (exitinfo.Charset == FTNC_NONE) {
	Chg_Charset();
    }

    setlocale(LC_CTYPE, getlocale(exitinfo.Charset)); 	 
    Syslog('b', "setlocale(LC_CTYPE, NULL) returns \"%s\"", printable(setlocale(LC_CTYPE, NULL), 0));

    GetLastUser();
    StartTime = xstrcpy(GetLocalHM());
    ChangeHomeDir(exitinfo.Name, exitinfo.Email);

    Syslog('+', "User successfully logged into BBS");
    Syslog('+', "Level %d (%s), %d mins. left, port %s", exitinfo.Security.level, LIMIT.Description, exitinfo.iTimeLeft, pTTY);
    Time2Go = time(NULL);
    Time2Go += exitinfo.iTimeLeft * 60;
    iUserTimeLeft = exitinfo.iTimeLeft;

    IsDoing("Welcome screens");
    DisplayFile((char *)"mainlogo");
    DisplayFile((char *)"welcome");

    /*
     * The following files are only displayed if the user has
     * turned the Bulletins on.
     */
    if (exitinfo.ieNEWS) {
	DisplayFile((char *)"welcome1");
	DisplayFile((char *)"welcome2");
	DisplayFile((char *)"welcome3");
	DisplayFile((char *)"welcome4");
	DisplayFile((char *)"welcome5");
	DisplayFile((char *)"welcome6");
	DisplayFile((char *)"welcome7");
	DisplayFile((char *)"welcome8");
	DisplayFile((char *)"welcome9");

	snprintf(temp, PATH_MAX, "%s", (char *) GetDateDMY() );
	if ((strcmp(exitinfo.sDateOfBirth, temp)) == 0)
	    DisplayFile((char *)"birthday");

	/*
	 * Displays file if it exists DD-MM.A??
	 */
	snprintf(temp, PATH_MAX, "%s", (char *) GetDateDMY());
	strcpy(temp1, "");
	strncat(temp1, temp, 5);
	snprintf(temp, PATH_MAX, "%s", temp1);
	DisplayFile(temp);
	
	/*
	 * Displays users security file if it exists
	 */
	snprintf(temp, PATH_MAX, "sec%d", exitinfo.Security.level);
	DisplayFile(temp);

	/*
	 * Display News file
	 */
	DisplayFile((char *)"news");
    }

    /*
     * Display Onceonly file, first get the date of that
     * file, search order is the same as in DisplayFile()
     */
    st.st_mtime = 0;
    snprintf(temp, PATH_MAX, "%s/share/int/txtfiles/%s/onceonly.ans", getenv("FTND_ROOT"), lang.lc);
    stat(temp, &st);
    if (st.st_mtime == 0) {
	snprintf(temp, PATH_MAX, "%s/share/int/txtfiles/%s/onceonly.ans", getenv("FTND_ROOT"), CFG.deflang);
	stat(temp, &st);
    }
    if (st.st_mtime == 0) {
	snprintf(temp, PATH_MAX, "%s/share/int/txtfiles/%s/onceonly.asc", getenv("FTND_ROOT"), lang.lc);
	stat(temp, &st);
	if (st.st_mtime == 0) {
	    snprintf(temp, PATH_MAX, "%s/share/int/txtfiles/%s/onceonly.asc", getenv("FTND_ROOT"), CFG.deflang);
	    stat(temp, &st);
	}
    }

    if ((st.st_mtime != 0) && (LastLogin < st.st_mtime))
	DisplayFile((char *)"onceonly");
	
    OLR_SyncTags();

    if (exitinfo.MailScan) {
	IsDoing("New mail check");
	CheckMail();
    }

    /*
     * We don't show new files to new users.
     */
    if (exitinfo.ieFILE && (!IsNew)) {
	IsDoing("New files check");
	NewfileScan(FALSE);
    }
    
    /* 
     * Copy last file Area in to current Area 
     */
    SetFileArea(exitinfo.iLastFileArea);

    /*
     * Copy Last Message Area in to Current Msg Area
     */
    SetMsgArea(usrconfig.iLastMsgArea);
    SetEmailArea((char *)"mailbox");

    /*
     * Set or Reset the DoNotDisturb flag, now is the time
     * we may be interrupted.
     */
    UserSilent(usrconfig.DoNotDisturb);

    /*
     * Start the menu.
     */
    menu();
}
Пример #2
0
Файл: file.c Проект: bbs-io/mbse
/*
 * Upload a file.
 */
int Upload()
{
    int		    Area, rc;
    unsigned int    OldArea;
    char	    *arc, *temp;
    up_list	    *up = NULL, *tmpf;

    WhosDoingWhat(UPLOAD, NULL); 
    Enter(1);
    Area = OldArea = iAreaNumber;

    /*
     * If there is a special upload area for the current area
     * then select it.
     */
    if (area.Upload)
	Area = area.Upload;
    SetFileArea(Area);
    Syslog('+', "Upload area is %d %s", Area, area.Name);

    /*
     * Check upload access for the real upload directory.
     */
    if (!Access(exitinfo.Security, area.UPSec)) {
	Enter(1);
	/* You do not have enough access to upload to this area */
	pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(278));
	Enter(2);
	SetFileArea(OldArea);
	Pause();
	return 0;
    }

    clear();
    Enter(2);

    rc = upload(&up);

    if (rc) {
	Syslog('+', "Upload failed, rc=%d", rc);
	SetFileArea(OldArea);
	return 0;
    }
    Syslog('b', "upload done, start checks");

    Enter(2);
    pout(CFG.UnderlineColourF, CFG.UnderlineColourB, (char *)"Checking your upload(s)");
    Enter(1);

    temp = calloc(PATH_MAX, sizeof(char));
    for (tmpf = up; tmpf; tmpf = tmpf->next) {
	snprintf(temp, PATH_MAX, "%s/%s/upl", CFG.bbs_usersdir, exitinfo.Name);
	chdir(temp);

	Syslog('b', "Checking upload %s", tmpf->filename);
	if ((arc = GetFileType(tmpf->filename)) == NULL) {
	    /*
	     * If the filetype is unknown, it is probably 
	     * a textfile or so. Import it direct.
	     */
	    Syslog('b', "Unknown file type");
	    if (!ScanDirect(basename(tmpf->filename)))
		ImportFile(tmpf->filename, Area, FALSE, tmpf->size);
	} else {
	    /*
	     * We figured out the type of the uploaded file.
	     */
	    Syslog('b', "File type is %s", arc);

	    /*
	     * MS-DOS executables are handled direct.
	     */
	    if ((strcmp("EXE", arc) == 0) || (strcmp("COM", arc) == 0)) {
	        if (!ScanDirect(basename(tmpf->filename))) 
		   ImportFile(tmpf->filename, Area, FALSE, tmpf->size);
	    } else {
		switch (ScanArchive(basename(tmpf->filename), arc)) {
		    case 0: ImportFile(tmpf->filename, Area, TRUE, tmpf->size);
			    break;
		    case 1: break;
		    case 2: break;
		    case 3: /*
			     * No valid unarchiver found, just import after scanning,
			     * may catch macro viri.
			     */
			    if (!ScanDirect(basename(tmpf->filename)))
				ImportFile(tmpf->filename, Area, FALSE, tmpf->size);
			    break;
		}
	    }
	}
    }

    tidy_upload(&up);
    free(temp);
    Home();
    SetFileArea(OldArea);
    Pause();
    return 1;
}
Пример #3
0
Файл: file.c Проект: bbs-io/mbse
/*
 * Search for a file, called from the menu.
 */
int FilenameScan()
{
    FILE	    *pAreas;
    int		    Found, Count = 0;
    char	    mask[256];
    char	    *Name;
    _Tag	    T;
    unsigned int    OldArea;
    struct _fdbarea *fdb_area = NULL;

    Name     = calloc(81, sizeof(char));
    OldArea  = iAreaNumber;

    iLineCount = 2; /* Reset Line Counter to Zero */
    arecno     = 1; /* Reset Area Number to One  */

    Enter(2);
    /* Accepts wildcards such as : *.zip, *.gz, *.* */
    pout(WHITE, BLACK, (char *) Language(269));

    Enter(2);
    /* Enter filename to search for : */
    pout(LIGHTCYAN, BLACK, (char *) Language(271));

    colour(CFG.InputColourF, CFG.InputColourB);
    GetstrC(Name, 80);

    if ((strcmp(Name, "")) == 0) {
	free(Name);
	return 0;
    }

    strcpy(mask, re_mask(Name, TRUE));
    Syslog('+', "FilenameScan(): \"%s\" -> \"%s\"", Name, mask);
    free(Name);
    re_comp(mask);

    clear();
    /* File Search by Filename */
    pout(WHITE, BLACK, (char *) Language(272));
    Enter(1);
    InitTag();

    if ((pAreas = OpenFareas(FALSE)) == NULL)
	return 0;

    while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {
	if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0)) {

	    if ((fdb_area = mbsedb_OpenFDB(arecno, 30))) {
		Found = FALSE;
		Sheader();
		Nopper();

		while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
		    if (re_exec(fdb.Name) || re_exec(fdb.LName)) {
			if (!Found) {
			    Enter(2);
			    if (iLC(2) == 1) {
				SetFileArea(OldArea);
				return 1;
			    }
			    Found = TRUE;
			}

			memset(&T, 0, sizeof(T));
			T.Area   = arecno;
			T.Active = FALSE;
			T.Size   = fdb.Size;
			strncpy(T.SFile, fdb.Name, 12);
			strncpy(T.LFile, fdb.LName, 81);
			SetTag(T);
			Count++;
			if (ShowOneFile() == 1) {
			    SetFileArea(OldArea);
			    return 1;
			}
		    }

		} /* End of while */

		mbsedb_CloseFDB(fdb_area);
		if (Found) {
		    Enter(2);
		    if (iLC(2) == 1) {
			SetFileArea(OldArea);
			return 1;
		    }
		}

	    } /* End Check for LTSec */
	} /* if access */
	arecno++; /* Go to next file area */

    } /* End of Main */

    Syslog('+', "Found %d files", Count);
    fclose(pAreas);
    Enter(1);
    if (Count)
	Mark();
    else
	Pause();
    SetFileArea(OldArea);
    return 1;
}
Пример #4
0
Файл: file.c Проект: bbs-io/mbse
/*
 * Search for keyword, called from menu.
 */
int KeywordScan()
{
    FILE	    *pAreas;
    int		    i, z, y, Found, Count = 0;
    char	    *Name, *tmpname, *BigDesc, temp[81];
    _Tag	    T;
    unsigned int    OldArea;
    struct _fdbarea *fdb_area = NULL;

    Name     = calloc(81, sizeof(char));
    tmpname  = calloc(81, sizeof(char));
    BigDesc  = calloc(1230, sizeof(char));
    OldArea  = iAreaNumber;

    iLineCount = 2; /* Reset Line Counter to Zero */
    arecno     = 1; /* Reset Area Number to One */

    Enter(2);
    /* Enter keyword to use for Search: */
    pout(LIGHTCYAN, BLACK, (char *) Language(267));

    colour(CFG.InputColourF, CFG.InputColourB);
    GetstrC(Name, 80);

    if ((strcmp(Name, "")) == 0)
	return 0;

    strcpy(tmpname, tl(Name));
    strcpy(Name, "");
    y = strlen(tmpname);
    for (z = 0; z <  y; z++) {
	if (tmpname[z] != '*') {
	    snprintf(temp, 81, "%c", tmpname[z]);
	    strcat(Name, temp);
	}
    }
    Syslog('+', "KeywordScan(): \"%s\"", Name);

    clear();
    /* File search by keyword */
    pout(WHITE, BLACK, (char *) Language(268));
    Enter(1);
    InitTag();

    if ((pAreas = OpenFareas(FALSE)) == NULL)
	return 0;

    while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {

	if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0)) {

	    if ((fdb_area = mbsedb_OpenFDB(arecno, 30))) {
		Nopper();
		Found = FALSE;
		Sheader();

		while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
		    for (i = 0; i < 25; i++)
			snprintf(BigDesc, 1230, "%s%s", BigDesc, *(fdb.Desc + i));

		    if ((strstr(fdb.Name,Name) != NULL) || (strstr(tl(BigDesc), Name) != NULL)) {

			if (!Found) {
			    Enter(2);
			    if (iLC(2) == 1) {
				free(BigDesc);
				free(Name);
				free(tmpname);
				SetFileArea(OldArea);
				return 1;
			    }
			    Found = TRUE;
			}

			memset(&T, 0, sizeof(T));
			T.Area   = arecno;
			T.Active = FALSE;
			T.Size   = fdb.Size;
			strncpy(T.SFile, fdb.Name, 12);
			strncpy(T.LFile, fdb.LName, 80);
			SetTag(T);
			Count++;
			if (ShowOneFile() == 1) {
			    free(BigDesc);
			    free(Name);
			    free(tmpname);
			    SetFileArea(OldArea);
			    return 1;
			}
		    }
		    strcpy(BigDesc, "");  /* Clear BigDesc */

		} /* while */

		mbsedb_CloseFDB(fdb_area);
		if (Found) {
		    Enter(2);
		    if (iLC(2) == 1) {
			free(BigDesc);
			free(Name);
			free(tmpname);
			SetFileArea(OldArea);
			return 1;
		    }
		}

	    } /* End check for LTSec */
	} /* if access */
	arecno++; /* Go to next file area */
    } /* End of Main */

    Syslog('+', "Found %d files", Count);
    free(BigDesc);
    free(Name);
    free(tmpname);
    fclose(pAreas);
    Enter(1);
    if (Count)
	Mark();
    else
	Pause();
    SetFileArea(OldArea);
    return 1;
}
Пример #5
0
Файл: file.c Проект: bbs-io/mbse
/*
 * Download files already tagged, called from the menu.
 */
void Download(void)
{
    FILE	    *tf, *fd;
    int		    rc = 0, i, Count = 0, OldArea;
    char	    *local, *temp;
    int		    Size = 0, CostSize = 0, dsize;
    struct _fdbarea *fdb_area = NULL;
    down_list	    *dl = NULL, *tmpf;

    Enter(2);
    OldArea = iAreaNumber;
    WhosDoingWhat(DOWNLOAD, NULL);

    /*
     * Clean users tag directory.
     */
    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "-rf %s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
    execute_pth((char *)"rm", temp, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
    snprintf(temp, PATH_MAX, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
    CheckDir(temp);

    if ((tf = fopen("taglist", "r+")) == NULL) {
	Syslog('+', "Download command but no files marked");
	/* No files marked for download. */
	pout(LIGHTRED, BLACK, (char *) Language(258));
	Enter(2);
	Pause();
	return;
    }

    local   = calloc(PATH_MAX, sizeof(char));
    /* Checking your marked downloads, please wait... */
    pout(LIGHTMAGENTA, BLACK, (char *) Language(255));
    Enter(2);

    ReadExitinfo();
    while (fread(&Tag, sizeof(Tag), 1, tf) == 1) {
	if (Tag.Active) {

	    SetFileArea(Tag.Area);

	    /*
	     * Check password for selected file  FIXME: Where???
	     */
	    memset(&fdb, 0, sizeof(fdb));
	    if ((fdb_area = mbsedb_OpenFDB(Tag.Area, 30)) != NULL) {
		while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
		    if (strcmp(fdb.LName, Tag.LFile) == 0)
			break;
		}
		mbsedb_CloseFDB(fdb_area);
	    }

	    if (strcmp(fdb.LName, Tag.LFile) == 0) {
		Syslog('b', "Found file %s in area %d", fdb.LName, Tag.Area);
		if (fdb.Deleted) {
		    /* Sorry that file is unavailable for download */
		    snprintf(temp, 81, "%s (%s)", (char *) Language(248), fdb.LName);
		    poutCR(CFG.HiliteF, CFG.HiliteB, temp);
		    Tag.Active = FALSE;
		    Syslog('+', "File %s in area %d unavailable for download, deleted", fdb.LName, Tag.Area);
		}
	    }

	    if (Tag.Active) {
		/*
		 * Create/Append file description list while we're
		 * busy checking. If the users doesn't want it we
		 * can unlink it aftwerwards. We also insert CR
		 * characters to please the poor DOS (M$oft) users.
		 */
		snprintf(local, PATH_MAX, "./tag/filedesc.%d", exitinfo.Downloads % 256);
		if ((fd = fopen(local, "a")) != NULL) {
		    fprintf(fd, "%s (%s)\r\n", fdb.LName, fdb.Name);
		    for (i = 0; i < 25; i++) {
			if (strlen(fdb.Desc[i]) > 1)
			    fprintf(fd, "  %s\r\n", fdb.Desc[i]);
		    }
		    fprintf(fd, "\r\n");
		    fclose(fd);
		    Syslog('b', "Added info to %s", local);
		} else {
		    WriteError("Can't add info to %s", local);
		}

		snprintf(local, PATH_MAX, "%s/%s", sAreaPath, Tag.LFile);
		add_download(&dl, local, Tag.LFile, Tag.Area, fdb.Size, FALSE);

		Home();
	    } 

	    if (!Tag.Active) {
		/*
		 * Update the download active flag in the
		 * taglist
		 */
		fseek(tf, - sizeof(Tag), SEEK_CUR);
		fwrite(&Tag, sizeof(Tag), 1, tf);
		Syslog('b', "Download file %s marked inactive in taglist", Tag.LFile);
	    } else {
		/*
		 * Count file and sizes.
		 */
		Count++;
		Size += fdb.Size;
		if (!area.Free)
		    CostSize += fdb.Size;
	    }
	}
    }
    fclose(tf);

    /*
     * If anything left to download...
     */
    if (!Count) {
	SetFileArea(OldArea);
	unlink("taglist");
	/* No files marked for download */
	pout(LIGHTRED, BLACK, (char *) Language(258));
	Enter(2);
	Pause();
	free(temp);
	free(local);
	tidy_download(&dl);
	Syslog('+', "No files left to download");
	return;
    }

    /*
     * Add descriptions file to the queue.
     */
    snprintf(local, PATH_MAX, "%s/%s/tag/filedesc.%d", CFG.bbs_usersdir, exitinfo.Name, exitinfo.Downloads % 256);
    dsize = file_size(local);
    snprintf(temp, PATH_MAX, "filedesc.%d", exitinfo.Downloads % 256);
    add_download(&dl, local, temp, 0, dsize, TRUE);
    free(local);

    /* You have */ /* files( */ /* bytes) marked for download */
    snprintf(temp, PATH_MAX, "%s %d %s%d %s", (char *) Language(249), Count, (char *) Language(280), Size, (char *) Language(281));
    pout(YELLOW, BLACK, temp);
    Enter(2);

    if (!CheckBytesAvailable(CostSize)) {
	SetFileArea(OldArea);
	free(temp);
	tidy_download(&dl);
	return;
    }

    Pause();

    if ((rc = download(dl))) {
	/*
	 * Download error
	 */
	Syslog('+', "Download error rc=%d", rc);
	free(temp);
	tidy_download(&dl);
	return;
    }
    
    /*
     * Checking the successfull sent files, they are missing from
     * the ./tag directory. Failed files are still there.
     */
    PUTCHAR('\r');
    /* Updating download counters, please wait ... */
    pout(LIGHTCYAN, BLACK, (char *) Language(352));
    Count = Size = 0; 

    /*
     * Update downloadcounters, don't log anything because the state
     * of sucessfull sent files is already logged by the download
     * function.
     */
    if ((tf = fopen("taglist", "r+")) != NULL) {
	while (fread(&Tag, sizeof(Tag), 1, tf) == 1) {
	    PUTCHAR('.');
	    if (Tag.Active) {
		for (tmpf = dl; tmpf; tmpf = tmpf->next) {
		    if (strcmp(tmpf->remote, Tag.LFile) == 0) {
			if (tmpf->sent) {
		
			    Tag.Active = FALSE;
			    fseek(tf, - sizeof(Tag), SEEK_CUR);
			    fwrite(&Tag, sizeof(Tag), 1, tf);

			    /*
			     * Update the download counter and the last download date.
			     */
			    SetFileArea(Tag.Area);
			    if ((fdb_area = mbsedb_OpenFDB(Tag.Area, 30))) {
				while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
				    if (strcmp(fdb.LName, Tag.LFile) == 0)
					break;
				}
				Size += fdb.Size;
				fdb.TimesDL++;
				fdb.LastDL = time(NULL);
				if (mbsedb_LockFDB(fdb_area, 30)) {
				    fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
				    fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
				    mbsedb_UnlockFDB(fdb_area);
				}
				mbsedb_CloseFDB(fdb_area);
				Count++;
			    }
			}
			break;
		    }
		}
	    }
	}
	fclose(tf);
    }
    Enter(2);

    /*
     * Update the users record.
     */
    ReadExitinfo();

    exitinfo.Downloads += Count;          /* Increase download counter      */
    mib_downloads      += Count;
    exitinfo.DownloadK += (Size / 1024);  /* Increase amount download today */
    mib_kbdownload     += (Size / 1024);

    /*
     * Minus the amount downloaded today from downloadktoday
     * if less than zero, it won't let the user download anymore.
     */
    if (LIMIT.DownK || LIMIT.DownF) {
	exitinfo.DownloadKToday -= (Size / 1024);
    }

    WriteExitinfo();
    Pause();
    SetFileArea(OldArea);
    free(temp);
    tidy_download(&dl);
}
Пример #6
0
Файл: file.c Проект: bbs-io/mbse
/*
 * Select filearea, called from menu.
 */
void FileArea_List(char *Option)
{
    FILE    *pAreas;
    int	    iAreaCount = 6, Recno = 1, iOldArea, iAreaNum = 0;
    int	    iGotArea = FALSE; /* Flag to check if user typed in area */
    int	    offset;
    char    *temp;

    /*
     * Save old area, incase he picks a invalid area
     */
    iOldArea = iAreaNumber;
    if ((pAreas = OpenFareas(FALSE)) == NULL)
	return;

    /*
     * Count howmany records there are
     */
    fseek(pAreas, 0, SEEK_END);
    iAreaNum = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;

    /*
     * If there are menu options, select area direct.
     */
    if (strlen(Option) != 0) {

	if (strcmp(Option, "F+") == 0) {
	    while (TRUE) {
		iAreaNumber++;
		if (iAreaNumber > iAreaNum)
		    iAreaNumber = 1;

		offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize);
		if (fseek(pAreas, offset, 0) != 0) {
		    printf("Can't move pointer here");
		}

		fread(&area, areahdr.recsize, 1, pAreas);
		if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0))
		    break;
	    }
	}
	
	if (strcmp(Option, "F-") == 0) {
	    while (TRUE) {
		iAreaNumber--;
		if (iAreaNumber < 1)
		    iAreaNumber = iAreaNum;

		offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize);
		if (fseek(pAreas, offset, 0) != 0) {
		    printf("Can't move pointer here");
		}

		fread(&area, areahdr.recsize, 1, pAreas);
		if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0))
		    break;
	    }
	}
	    
	SetFileArea(iAreaNumber);
	Syslog('+', "File area %lu %s", iAreaNumber, sAreaDesc);
	fclose(pAreas);
	return;
    }

    /*
     * Interactive mode
     */
    clear();
    Enter(1);
    /* File Areas */
    pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(298));
    Enter(2);
    temp = calloc(81, sizeof(char));

    fseek(pAreas, areahdr.hdrsize, 0);

    while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {

	if ((Access(exitinfo.Security, area.LTSec)) && (area.Available)) {
	    area.Name[31] = '\0';
	    snprintf(temp, 81, "%5d", Recno);
	    pout(WHITE, BLACK, temp);
	    snprintf(temp, 81, " %c ", 46);
	    pout(LIGHTBLUE, BLACK, temp);
	    snprintf(temp, 81, "%-31s", area.Name);
	    pout(CYAN, BLACK, temp);
	    iAreaCount++;

	    if ((iAreaCount % 2) == 0) {
		Enter(1);
	    } else {
		PUTCHAR(' ');
	    }
	}

	Recno++; 

	if ((iAreaCount / 2) == rows) {
	    /* More (Y/n/=/Area #): */
	    pout(CFG.MoreF, CFG.MoreB, (char *) Language(207)); 
	    /*
	     * Ask user for Area or enter to continue
	     */
	    colour(CFG.InputColourF, CFG.InputColourB);
	    GetstrC(temp, 7);

	    if (toupper(*(temp)) == Keystroke(207, 1))
		break;

	    if ((strcmp(temp, "")) != 0) {
		iGotArea = TRUE;
		break;
	    }

	    iAreaCount = 2;
	}
    }

    /*
     * If user type in area above during area listing
     * don't ask for it again
     */
    if (!iGotArea) {
	Enter(1);
	/* Select Area: */
	pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(232));
	colour(CFG.InputColourF, CFG.InputColourB);
	GetstrC(temp, 80);
    } 

    /*
     * Check if user pressed ENTER
     */
    if ((strcmp(temp, "")) == 0) {
	fclose(pAreas);
	return;
    }

    iAreaNumber = atoi(temp);

    /*
     * Do a check in case user enters a negative value
     */
    if (iAreaNumber < 1) 
	iAreaNumber = 1;

    offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize); 
    if (fseek(pAreas, offset, 0) != 0) 
	printf("Can't move pointer there."); 
    else
	fread(&area, areahdr.recsize, 1, pAreas);

    /*
     * Do a check if area is greater or less number than allowed,
     * security access level, is oke, and the area is active.
     */
    if (iAreaNumber > iAreaNum || iAreaNumber < 1 || 
	    (Access(exitinfo.Security, area.LTSec) == FALSE) || 
	    (strlen(area.Name) == 0)) {
	Enter(1);
	/* Invalid area specified - Please try again ...*/
	pout(LIGHTRED, BLACK, (char *) Language(233));
	Enter(2);
	Pause();
	fclose(pAreas);
	iAreaNumber = iOldArea;
	SetFileArea(iAreaNumber);
	free(temp);
	return;
    }

    SetFileArea(iAreaNumber);
    Syslog('+', "File area %lu %s", iAreaNumber, sAreaDesc);

    /*
     * Check if file area has a password, if it does ask user for it
     */ 
    if ((strlen(area.Password)) > 2) {
	Enter(2);
	/* Please enter Area Password: */
	pout(WHITE, BLACK, (char *) Language(299));
	colour(CFG.InputColourF, CFG.InputColourB);
	GetstrC(temp, 20);
	Enter(1);

	if ((strcmp(temp, area.Password)) != 0) { 
	    /* Password is incorrect */
	    pout(LIGHTRED, BLACK, (char *) Language(234));
	    Syslog('!', "Incorrect File Area # %d password given: %s", iAreaNumber, temp);
	    SetFileArea(iOldArea);
	} else {
	    /* Password is correct */
	    pout(WHITE, BLACK, (char *) Language(235));
	}
	Enter(2);
	Pause();
    } 

    free(temp);
    fclose(pAreas);
}