home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume44 / rocat / part04 < prev    next >
Encoding:
Internet Message Format  |  1994-08-01  |  96.3 KB

  1. From: shaw@stortek.stortek.com (Greg Shaw)
  2. Newsgroups: comp.sources.misc
  3. Subject: v44i004:  rocat - Roman Catacombs BBS System v.0.75, Part04/09
  4. Date: 1 Aug 1994 12:08:47 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <31ja6v$b0f@sparky.sterling.com>
  9. X-Md4-Signature: ac4c2527a9c1d7a7030efcb176f071e2
  10.  
  11. Submitted-by: shaw@stortek.stortek.com (Greg Shaw)
  12. Posting-number: Volume 44, Issue 4
  13. Archive-name: rocat/part04
  14. Environment: Linux, GNU C++/libg++
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  rocat-0.75/src/files.C rocat-0.75/src/user.C
  21. # Wrapped by kent@sparky on Mon Jul 11 22:22:51 1994
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 4 (of 9)."'
  25. if test -f 'rocat-0.75/src/files.C' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'rocat-0.75/src/files.C'\"
  27. else
  28.   echo shar: Extracting \"'rocat-0.75/src/files.C'\" \(47604 characters\)
  29.   sed "s/^X//" >'rocat-0.75/src/files.C' <<'END_OF_FILE'
  30. X// Filename:    files.C
  31. X// Contents:    the files object methods
  32. X// Author:    Greg Shaw
  33. X// Created:    8/1/93
  34. X
  35. X/*
  36. XThis file is free software; you can redistribute it and/or modify it
  37. Xunder the terms of the GNU General Public License as published by the
  38. XFree Software Foundation; either version 2, or (at your option) any
  39. Xlater version.
  40. X
  41. XIn addition to the permissions in the GNU General Public License, the
  42. XFree Software Foundation gives you unlimited permission to link the
  43. Xcompiled version of this file with other programs, and to distribute
  44. Xthose programs without any restriction coming from the use of this
  45. Xfile.  (The General Public License restrictions do apply in other
  46. Xrespects; for example, they cover modification of the file, and
  47. Xdistribution when not linked into another program.)
  48. X
  49. XThis file is distributed in the hope that it will be useful, but
  50. XWITHOUT ANY WARRANTY; without even the implied warranty of
  51. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  52. XGeneral Public License for more details.
  53. X
  54. XYou should have received a copy of the GNU General Public License
  55. Xalong with this program; see the file COPYING.  If not, write to
  56. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  57. X
  58. X#ifndef _FILES_C_
  59. X#define _FILES_C_
  60. X
  61. X#include "bbshdr.h"
  62. X
  63. X// Function:    constructor
  64. X// Purpose:    initialize the files object to a known state
  65. X// Input:    user - the card to use for the user using the BBS currently
  66. X// Output:    none
  67. X// Author:    Greg Shaw
  68. X// Created:    8/1/93
  69. X
  70. Xfiles::files()
  71. X{
  72. X    acl = 0;
  73. X    num_files = 0;
  74. X    name[0] = 0;
  75. X    age = 0;
  76. X    long_desc[0] = 0;
  77. X    sysop[0] = 0;
  78. X    numsel = 0;
  79. X    ksel = 0;
  80. X};
  81. X
  82. X// Function:    edit_file
  83. X// Purpose:    edit the information for a file
  84. X// Input:    item - the information for a particular file
  85. X// Output:    The file may be deleted or edited.  In either case, the
  86. X//        file information is updated.
  87. X// Author:    Greg Shaw
  88. X// Created:    4/27/94
  89. X
  90. Xint files::edit_file(FInfo *item)
  91. X{
  92. X    int    edited;            // edited anything?
  93. X    int    linenum;        // line counter for description
  94. X    int    off;            // char offset into line
  95. X    char    *editor;        // name of their 'favorite' editor
  96. X    char    tmpstr[255];        // temp str
  97. X    char    oldname[MAX_FILENAMELENGTH];    // name prior to change
  98. X    char    filename[255];        // new name of file
  99. X    char     machreq[255];        // machine requirements
  100. X    char    c;
  101. X    char    ldesc[3][100];        // long description
  102. X    FILE    *infile, *outfile;    // files
  103. X
  104. X    clear();
  105. X    strcpy(oldname,item->name);    // save old name so we can find it later
  106. X    machreq[0] = 0;
  107. X    ldesc[0][0] = 0;
  108. X    sprintf(tmpstr,"Filename: %s",item->name);
  109. X    sstrcr(tmpstr);
  110. X    cr();
  111. X    sstr("Edit, Delete or Quit? " );
  112. X    while (c = tolower(gch(1)), c != 'e' && c != 'd' && c != 'q');
  113. X    cr();
  114. X    if (c == 'q')
  115. X        return(0);
  116. X    else if (c == 'd')    // delete
  117. X        return(update_information(item, NULL, ldesc, machreq, 1));
  118. X    else if (c == 'e')    // edit
  119. X    {
  120. X        edited = 0;
  121. X        while (1)    // return will get out
  122. X        {
  123. X            sstrcr("Current file information:");
  124. X            cr();
  125. X            info(item,ldesc, machreq);
  126. X            cr();
  127. X            sstrcr("1.  Name");
  128. X            sstrcr("2.  Short Description");
  129. X            sstrcr("3.  Uploader");
  130. X            sstrcr("4.  Number of Downloads");
  131. X            sstrcr("5.  Machine Requirements");
  132. X            sstrcr("6.  Long Description");
  133. X            sstrcr("q.  Done editing, quit");
  134. X            cr();
  135. X            sstr("Edit which? ");
  136. X            while (c = tolower(gch(1)), c != 'q' && (c < '0' || c > '6') );
  137. X            cr();
  138. X            cr();
  139. X            switch(c)
  140. X            {
  141. X            case 'q':
  142. X                if (edited)
  143. X                    return(update_information(item,oldname,ldesc,machreq,0));
  144. X                return(0);
  145. X            case '1':    // name
  146. X                edited++;
  147. X                sstr("New name? ");
  148. X                gstr(item->name,MAX_FILENAMELENGTH);
  149. X                break;
  150. X            case '2':    // short description
  151. X                edited++;
  152. X                sstr("New short description? ");
  153. X                gstr(item->sdesc,60);
  154. X                break;
  155. X            case '3':    // uploader
  156. X                edited++;
  157. X                sstr("New uploader? ");
  158. X                gstr(item->uploader,40);
  159. X                break;
  160. X            case '4':    // number of downloads
  161. X                edited++;
  162. X                sstr("New number of downloads? ");
  163. X                gstr(tmpstr,5);
  164. X                sscanf(tmpstr,"%d",&item->numdls);
  165. X                break;
  166. X            case '5':    // machine requirements
  167. X                edited++;
  168. X                sstr("New machine requirements? ");
  169. X                gstr(machreq,40);
  170. X                break;
  171. X            case '6':    // long description
  172. X                edited++;
  173. X                // now get the long description
  174. X                // create temp file
  175. X                strcpy(tmpstr,"bbsXXXXXX");
  176. X                mktemp(tmpstr);
  177. X                if (tmpstr[0] == 0)
  178. X                {
  179. X                    ap_log("Unable to create temp file for long description editing.");
  180. X                    return(0);
  181. X                }
  182. X                // got temp file.  pass to system.
  183. X                cr();
  184. X                cr();
  185. X                sstrcr("The long description will be placed in a file..");
  186. X                sstrcr("Note: Anything more than 3 lines will be ignored.");
  187. X
  188. X                waitcr();
  189. X                strcpy(filename,tmpstr);
  190. X                strcpy(tmpstr,editor);
  191. X                if (editor = getenv("EDITOR"), editor == NULL)
  192. X                {
  193. X                    sstrcr("I am unable to find your EDITOR environment variable.");
  194. X                    sstrcr("In the future, setting the EDITOR environment variable will");
  195. X                    sstrcr("allow use of your editor of preference");
  196. X                    cr();
  197. X                    sstrcr("Defaulting to the 'vi' editor.");
  198. X                    waitcr();
  199. X                    strcpy(tmpstr,"vi");
  200. X                }
  201. X                else
  202. X                    strcpy(tmpstr,editor);
  203. X                strcat(tmpstr," /tmp/");
  204. X                strcat(tmpstr,filename);
  205. X                sysint(tmpstr);
  206. X                strcpy(tmpstr,"/tmp/");
  207. X                strcat(tmpstr,filename);    // now open file
  208. X                if (infile = bopen(tmpstr,"r"), infile == NULL)
  209. X                {
  210. X                    fprintf(outfile,"[D ]\n");
  211. X                    fprintf(outfile,"[E ]\n");
  212. X                    fprintf(outfile,"[F ]\n");
  213. X                    continue;
  214. X                }
  215. X                // now digest file
  216. X                linenum = 0;
  217. X                off = 0;
  218. X                ldesc[linenum][0] = 0;
  219. X                while (!feof(infile))
  220. X                {
  221. X                    while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile))
  222. X                        tmpstr[off++] = c;
  223. X                    tmpstr[off] = 0;
  224. X                    strcpy(ldesc[linenum],tmpstr);
  225. X                    linenum++;
  226. X                    off = 0;
  227. X                }
  228. X                bclose(infile);
  229. X                sprintf(tmpstr,"/tmp/%s",filename);
  230. X                if (unlink(tmpstr))    // remove temp file
  231. X                {
  232. X                    ap_log("file edit: unable to remove temp file.");
  233. X                    // not fatal
  234. X                }
  235. X            }
  236. X        }
  237. X    }
  238. X    else    // unknown
  239. X    {
  240. X        ap_log("Unknown quantity found in edit_file.");
  241. X        return(0);
  242. X    }
  243. X    return(0);
  244. X};
  245. X
  246. X// Function:    create
  247. X// Purpose:    create a files section.  read all file information from 
  248. X//        directory and insert into files header file.
  249. X// Input:    open must be called prior to this one.  the name of the
  250. X//        files section must be in the object.
  251. X// Output:    a new files section header file is created in the
  252. X//        $(BBS)/fileshdr directory.
  253. X// Author:    Greg Shaw
  254. X// Created:    8/4/93
  255. X// Notes:    *THIS IS VERY DANGEROUS*  It should only be done on BBS
  256. X//        files area initialization.  It will overwrite the 'old'
  257. X//        files header, losing any information that was there.
  258. X
  259. Xint files::create(void)
  260. X{
  261. X    FILE    *outfile;    // output file
  262. X    DIR    *fdir;        // directory file descriptor
  263. X    struct dirent *dentry;    // directory entry
  264. X    struct stat fistat;    // file status record
  265. X    time_t    now;        // date of file added (today)
  266. X    char    bbsdir[255];    // bbs directory
  267. X    char    tmpstr[255];    // tmpstr
  268. X
  269. X    time(&now);
  270. X    strcpy(bbsdir,getenv("BBSDIR"));     // not checking error
  271. X    strcpy(tmpstr,bbsdir);
  272. X    strcat(tmpstr,"/filehdr/");    // tack on files header
  273. X    strcat(tmpstr,name);
  274. X    if (outfile = bopen(tmpstr,"w"), outfile == NULL)
  275. X    {
  276. X        printf("Unable to open files section header %s",name);
  277. X    }
  278. X    strcpy(tmpstr,bbsdir);
  279. X    strcat(tmpstr,"/files/");
  280. X    strcat(tmpstr,dn_path);
  281. X    if (fdir = opendir(tmpstr), fdir == NULL)
  282. X    {
  283. X        printf("Unable to open directory %s for reading.\n",tmpstr);
  284. X        bclose(outfile);
  285. X        exit(0);
  286. X    }
  287. X    // ok.  output file is open. directory is open.  doit.
  288. X    while (dentry = readdir(fdir), dentry != NULL)
  289. X    {
  290. X        strcpy(tmpstr,bbsdir);
  291. X        strcat(tmpstr,"/files/");
  292. X        strcat(tmpstr,dn_path);
  293. X        strcat(tmpstr,"/");
  294. X        strcat(tmpstr,dentry->d_name);    // for stat
  295. X        if (stat(tmpstr,&fistat) == 0 && S_ISREG(fistat.st_mode))
  296. X        {
  297. X            fprintf(outfile,"[A sysop 0 %s ]\n",dentry->d_name);
  298. X            fprintf(outfile,"[B ]\n");
  299. X            fprintf(outfile,"[C ]\n");
  300. X            fprintf(outfile,"[D ]\n");
  301. X            fprintf(outfile,"[E ]\n");
  302. X            fprintf(outfile,"[F ]\n");
  303. X        }
  304. X    }
  305. X    closedir(fdir);
  306. X    bclose(outfile);    
  307. X    strcpy(tmpstr,bbsdir);
  308. X    strcat(tmpstr,"/filehdr/");    // tack on files header
  309. X    strcat(tmpstr,name);
  310. X    chmod(tmpstr,0775);
  311. X    chown(tmpstr,bbs_uid(),bbs_gid());    // change owner to bbs
  312. X    return(0);
  313. X};
  314. X// Function:    download
  315. X// Purpose:    download file(s) from the BBS
  316. X// Input:    list - an array of FInfo pointers (file records)
  317. X//        num - the number of records (files)
  318. X// Output:    if everything works well, and the karma of the universe aligns with the
  319. X//        BBSs, it will download files.
  320. X// Author:     Greg Shaw
  321. X// Created:    8/4/93
  322. X
  323. Xint files::download(FInfo *list[], int num, int increment)
  324. X{
  325. X    FILE    *infile;    // protocols file
  326. X    time_t    now;        // loop (5sec) counter
  327. X    time_t    then;        // loop (5sec) counter
  328. X    int    off;        // offset into line
  329. X    int    x;
  330. X    int    numprot;    // number of 'real' protocols
  331. X    int    protsel;    // index of selected protocol
  332. X    int    done;        // loop boolean
  333. X    char    c;        // one char from file
  334. X    char    tmpstr[255];    // temp str 
  335. X    char    comm[MAX_DL_COMMANDS][50];    // 15 commands max
  336. X    char    key[MAX_DL_COMMANDS];    // key for selecting command
  337. X    char    text[MAX_DL_COMMANDS][50];    // text describing command
  338. X    char    line[255];
  339. X
  340. X    if (!(num > 0))
  341. X        return(0);
  342. X    // Ok.  Change current working directory to files download area
  343. X    strcpy(tmpstr,getenv("BBSDIR"));
  344. X    strcat(tmpstr,"/files/");
  345. X    strcat(tmpstr,dn_path);
  346. X    chdir(tmpstr);    // change to files download directory (so local naming works)
  347. X    strcpy(tmpstr,getenv("BBSDIR"));
  348. X    strcat(tmpstr,"/config/protocols");
  349. X    // read protocols file.  digest.  display options to user.
  350. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  351. X    {
  352. X        ap_log("Unable to open config/protocols file.");
  353. X        return(0);
  354. X    }
  355. X    // now read protocols file.
  356. X    numprot = 0;
  357. X    while (!feof(infile))
  358. X    {
  359. X        off = 0;
  360. X        while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  361. X            line[off++] = c;
  362. X        // now digest line
  363. X        line[off] = 0;        // add null (for posterity) (and possibly anterity)
  364. X        if (off < 5 || feof(infile))    // line can't be less than 5 chars long
  365. X            continue;
  366. X        if (line[0] == 'D')    // we care about download only
  367. X        {
  368. X            // get command
  369. X            // note: this is pretty nasty.  Beer (good) and programming
  370. X            // are not necessarily mutually exclusive. 
  371. X            // although beer and excellent programming may be.
  372. X            off = 2;
  373. X            while (line[off] != '|' && line[off] != 0)
  374. X            {
  375. X                comm[numprot][off-2] = line[off++];
  376. X            }
  377. X            comm[numprot][off-2] = 0;    // add null
  378. X            off++;    // skip |    
  379. X            key[numprot] = line[off++];    // get hot key
  380. X            off++;    // skip |    
  381. X            x = off;    // give an offset
  382. X            while (line[off] != 0)
  383. X                text[numprot][off - x] = line[off++];
  384. X            text[numprot++][off-x] = 0;
  385. X        }
  386. X    }
  387. X    bclose(infile);
  388. X    // now show the bastich the protocols and let him choose...
  389. X    cr();
  390. X    sstrcr("Select Download Protocol: (or q to quit)");
  391. X    cr();
  392. X    for (x=0; x<numprot; x++)
  393. X        sstrcr(text[x]);
  394. X    cr();
  395. X    sstr("Your choice? ");
  396. X    done = 0;
  397. X    while (!done)
  398. X    {
  399. X        c = gch(1);
  400. X        if (c == 'q')
  401. X            return(0);
  402. X        for (x=0; x<numprot; x++)
  403. X            if (key[x] == c)
  404. X            {
  405. X                done++;
  406. X                protsel = x;
  407. X            }
  408. X    }    
  409. X    // Ok.  Got protocol.  Now do the download.
  410. X    cr();
  411. X    cr();
  412. X    sstrcr("Ready to start download.");
  413. X    cr();
  414. X    strcpy(tmpstr,comm[protsel]);
  415. X    for (x=0; x<num; x++)
  416. X    {
  417. X        strcat(tmpstr," ");
  418. X        strcat(tmpstr,list[x]->name);
  419. X    }    
  420. X    strcat(tmpstr," > /dev/null"); // pipe all stdout to /dev/null
  421. X    // ok.  pass to system
  422. X    waitcr();
  423. X    sysint(tmpstr);
  424. X    for (x=0; x<num; x++)
  425. X    {
  426. X        sprintf(tmpstr,"%s downloaded %s",username(),list[x]->name);
  427. X        ap_log(tmpstr);
  428. X    }    
  429. X    increment_dls(list,num);
  430. X    time(&then);
  431. X    while (time(&now), now - then < 5)
  432. X        fflush(stdin);    // trash any additional garbage left on line
  433. X    return(num);
  434. X};
  435. X
  436. X// Function:    increment_dls
  437. X// Purpose:    increment the number of downloads for the files downloaded
  438. X// Input:    list - the information for the files
  439. X// Output:    none
  440. X// Author:    Greg Shaw
  441. X// Created:    8/10/93
  442. X
  443. Xint files::increment_dls(FInfo *list[], int num)
  444. X{
  445. X    FILE    *infile;
  446. X    FILE    *outfile;
  447. X    int    x;
  448. X    int    off;
  449. X    int    numdls;
  450. X    char    uploader[10];
  451. X    char    numdone[20];    // max 20 files can be downloaded
  452. X    char    line[150];
  453. X    char    tmpstr[255];
  454. X    char    fname[MAX_FILENAMELENGTH+1];
  455. X    char    fname2[MAX_FILENAMELENGTH+1];
  456. X    char    fname3[MAX_FILENAMELENGTH+1];
  457. X    char    c;
  458. X    
  459. X    for (x=0; x< 20; x++)
  460. X        numdone[x] = 0;
  461. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  462. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  463. X    {
  464. X        sprintf(tmpstr,"Unable to open %s for read.",name);
  465. X        ap_log(tmpstr);
  466. X        return(0);
  467. X    }
  468. X    sprintf(tmpstr,"%s/filehdr/%s.new",getenv("BBSDIR"),name);
  469. X    if (outfile = bopen(tmpstr,"w"), outfile == NULL)
  470. X    {
  471. X        sprintf(tmpstr,"Unable to open %s.new for write.",name);
  472. X        ap_log(tmpstr);
  473. X        return(0);
  474. X    }
  475. X    while (!feof(infile))
  476. X    {
  477. X        off = 0;
  478. X        while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile))    
  479. X            line[off++] = c;
  480. X        line[off] = 0;
  481. X        if (line[0] == '[' && line[1] == 'A')    // first line?
  482. X        {
  483. X            fname2[0] = 0;
  484. X            fname3[0] = 0;
  485. X            sscanf(&line[2],"%s %d %s", uploader, &numdls, fname, fname2, fname3);
  486. X            if (strlen(fname2) > 0 && fname2[0] != ']')
  487. X            {
  488. X                sprintf(tmpstr,"%s %s",fname,fname2);
  489. X                strcpy(fname,tmpstr);
  490. X            }
  491. X            if (strlen(fname3) > 0 && fname3[0] != ']')
  492. X            {
  493. X                sprintf(tmpstr,"%s %s",fname,fname3);
  494. X                strcpy(fname,tmpstr);
  495. X            }
  496. X            for (x=0; x< num; x++)
  497. X                if (!numdone[x] && strcmp(fname,list[x]->name) == 0 )
  498. X                {
  499. X                    numdone[x] = 1;
  500. X                    numdls++;
  501. X                }
  502. X            fprintf(outfile,"[A %s %d %s ]\n",uploader, numdls, fname);
  503. X        }
  504. X        else if (strcmp(line,"") != 0)
  505. X            fprintf(outfile,"%s\n",line);
  506. X    }
  507. X    bclose(infile);
  508. X    bclose(outfile);
  509. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  510. X    sprintf(line,"%s/filehdr/%s.old",getenv("BBSDIR"),name);
  511. X    rename(tmpstr,line);    // rename file
  512. X    sprintf(tmpstr,"%s/filehdr/%s.new",getenv("BBSDIR"),name);
  513. X    sprintf(line,"%s/filehdr/%s",getenv("BBSDIR"),name);
  514. X    rename(tmpstr,line);    // rename file
  515. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  516. X    chmod(tmpstr,0775);
  517. X    chown(tmpstr,bbs_uid(),bbs_gid());    // change owner to bbs
  518. X    return(0);
  519. X};
  520. X
  521. X// Function:    info
  522. X// Purpose:    get info on a file and display to user
  523. X// Input:    fptr - a FInfo pointer (NULL to prompt user for filename)
  524. X// Output:    the long information is shown to user
  525. X// Author:    Greg Shaw
  526. X// Created:    8/10/93
  527. X
  528. Xint files::info(FInfo *fptr, char ldesc[3][100], char *machreq)
  529. X{
  530. X    char    tmpstr[255];
  531. X    char    filename[MAX_FILENAMELENGTH+1];    // name of file (if fptr NULL)
  532. X    char    line[255];    // one line of description
  533. X    char    datestr[12];    // date of file upload
  534. X    char    c;
  535. X    int    x;
  536. X    int    lp;        // number of lines of description printed
  537. X    int    off;        // offset into line
  538. X    int    state;        // which line are we working on?
  539. X    int    numlines=0;    // number of lines used for info
  540. X    FILE    *infile;
  541. X    FInfo    *rec;
  542. X    struct tm    *tmrec;    // date representation
  543. X
  544. X    if (fptr == NULL)
  545. X    {
  546. X        // get file from user
  547. X        sstr("Get info on which file? (q to quit) ");
  548. X        gstr(filename,MAX_FILENAMELENGTH);
  549. X        if (strcmp(filename,"q")==0)
  550. X            return(0);
  551. X        list_obj.top();
  552. X        rec = list_obj.next();
  553. X        while (strcmp(rec->name,filename) != 0 && rec != NULL)
  554. X            rec = list_obj.next();
  555. X        if (rec == NULL)
  556. X        {
  557. X            sprintf(tmpstr,"Unable to find a file named %s.",filename);
  558. X            sstrcr(tmpstr);
  559. X            waitcr();
  560. X            return(0);
  561. X        }
  562. X    }
  563. X    else
  564. X        rec = fptr;
  565. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  566. X    if (ldesc != NULL && strlen(ldesc[0]) != 0)// if we have description already, don't bother looking for it
  567. X    {
  568. X        tmrec = localtime(&rec->date);
  569. X        strftime(datestr,11,"%x",tmrec);
  570. X        sprintf(tmpstr,"Name: %-14.14s  Size: %8d  Uploaded on: %s by: %s ",
  571. X        rec->name,rec->size,datestr,rec->uploader);
  572. X        sstrcr(tmpstr);
  573. X        sprintf(tmpstr,"    Downloads: %2d  Short Description: %s",rec->numdls,rec->sdesc);
  574. X        sstrcr(tmpstr);
  575. X        sprintf(tmpstr,"    Avail? %c  Machine Requirements: %s",rec->avail,machreq);
  576. X        sstrcr(tmpstr);
  577. X        for (x=0; x<3; x++)
  578. X        {
  579. X            sstr("   ");
  580. X            sstrcr(ldesc[x]);
  581. X        }
  582. X        return(0);
  583. X    }
  584. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  585. X    {
  586. X        sprintf(tmpstr,"Unable to open files section %s.",name);
  587. X        ap_log(tmpstr);
  588. X        sstrcr("No files found.");
  589. X        waitcr();
  590. X        return(0);
  591. X    }
  592. X    if (fseek(infile,rec->filepos,0) != 0)
  593. X    {
  594. X        sprintf(tmpstr,"Unable to set position in %s to %ld.",name,rec->filepos);
  595. X        ap_log(tmpstr);
  596. X        return(0);
  597. X    }
  598. X    // Ok.  right place.  now let's read the beastie
  599. X    tmrec = localtime(&rec->date);
  600. X    strftime(datestr,11,"%x",tmrec);
  601. X    sprintf(tmpstr,"Name: %-14.14s  Size: %8d  Uploaded on: %s by: %s ",
  602. X    rec->name,rec->size,datestr,rec->uploader);
  603. X    sstrcr(tmpstr);
  604. X    sprintf(tmpstr,"    Downloads: %2d  Short Description: %s",rec->numdls,rec->sdesc);
  605. X    sstrcr(tmpstr);
  606. X    numlines += 2;
  607. X    state = 0;
  608. X    lp = 0;
  609. X    while (state < 4 && !feof(infile))
  610. X    {
  611. X        off = 0;
  612. X        while (c = fgetc(infile), c != ']' && !feof(infile))
  613. X            line[off++] = c;
  614. X        line[off] = 0;
  615. X        if (feof(infile))
  616. X            continue;
  617. X        if (c == ']')    // if got right bracket skip rest of line
  618. X            while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile));
  619. X        state++;
  620. X        switch(state)
  621. X        {
  622. X        case 1:    // machine requirements line
  623. X            sprintf(tmpstr,"    Avail? %c  Machine Requirements: %s",rec->avail,&line[2]);
  624. X            sstrcr(tmpstr);
  625. X            if (machreq != NULL)
  626. X                strcpy(machreq,&line[2]);
  627. X            numlines++;
  628. X            lp++;
  629. X            break;
  630. X        case 2:    // first long description line
  631. X            if (strcmp(&line[2]," ")!=0)
  632. X            {
  633. X                sstr("   ");
  634. X                sstrcr(&line[2]);
  635. X                numlines++;
  636. X                lp++;
  637. X            }
  638. X            if (ldesc != NULL)    // save long desc for return
  639. X                strcpy(ldesc[0],&line[2]);
  640. X            break;
  641. X        case 3:    // second long description line
  642. X            if (strcmp(&line[2]," ")!=0)
  643. X            {
  644. X                sstr("   ");
  645. X                sstrcr(&line[2]);
  646. X                numlines++;
  647. X                lp++;
  648. X            }
  649. X            if (ldesc != NULL)    // save long desc for return
  650. X                strcpy(ldesc[1],&line[2]);
  651. X            break;
  652. X        case 4:    // third long description line
  653. X            if (strcmp(&line[2]," ")!=0)
  654. X            {
  655. X                sstr("   ");
  656. X                sstrcr(&line[2]);
  657. X                numlines++;
  658. X                lp++;
  659. X            }
  660. X            if (ldesc != NULL)    // save long desc for return
  661. X                strcpy(ldesc[2],&line[2]);
  662. X        }
  663. X    }
  664. X    if (lp == 0)
  665. X    {
  666. X        sstrcr("   No description given.");
  667. X        numlines++;
  668. X    }
  669. X    return(numlines);
  670. X};
  671. X
  672. X
  673. X// Function:    list
  674. X// Purpose:    list the files found in the section
  675. X// Input:    can_download - true if give user option to download
  676. X//        kused - the amount of K used by the user today
  677. X// Output:    a files listing
  678. X// Author:    Greg Shaw
  679. X// Created:    8/1/93
  680. X
  681. Xint files::list(int can_download, CardRec *user, int *kused, time_t since_time, float uratio)
  682. X{
  683. X    FILE    *infile;    
  684. X    FInfo    *flist[20];    // five files on screen at once
  685. X    FInfo    *mlist[20];    // the file info for files he has marked
  686. X    FInfo    *rec;        // temporary rec
  687. X    struct tm *tmrec;
  688. X    time_t    now;        // time conversion
  689. X    time_t    then;        // used for idle timeout
  690. X    time_t    fromdate;    // date to show the user 'from'
  691. X    char    tmpstr[255];
  692. X    char    fname[255];
  693. X    char    datestr[11];
  694. X    char    *bbsdir;
  695. X    char    c;
  696. X    int    day,mon,year;    // for 'from' date selection
  697. X    int    display_dir;    // direction of display
  698. X    int    t;
  699. X    int    off;
  700. X    int    x;        // counter
  701. X    int    done;        // main loop counter
  702. X    int    numlines;    // number of descriptions on screen
  703. X    int    numfiles;    // number of files marked
  704. X    int    ksel;        // amount of 'k' selected for download
  705. X    int    oneline;    // one line or multiple lines?
  706. X    int    numdownls;    // number of files user downloaded
  707. X    int    inactivity;    // inactivity timeout
  708. X
  709. X    numdownls = 0;
  710. X    bbsdir = getenv("BBSDIR");
  711. X    strcpy(tmpstr,bbsdir);     // not checking because he shouldn't
  712. X                    // get here if bbsdir not set
  713. X    strcat(tmpstr,"/filehdr/");    // tack on files header
  714. X    strcat(tmpstr,name);        // add name
  715. X    strcpy(fname,tmpstr);
  716. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  717. X    {
  718. X        sprintf(tmpstr,"Unable to open %s files section.",name);
  719. X        ap_log(tmpstr);
  720. X        sstrcr("No files found.");
  721. X        waitcr();
  722. X        return(0);
  723. X    }
  724. X    // got the file.  let's ask him what he wants
  725. X    clear();
  726. X    sstrcr("List files as:");
  727. X    cr();
  728. X    sstrcr("1.  One line descriptions. (one line per file)");
  729. X    sstrcr("2.  Full file descriptions. (4 lines per file)");
  730. X    cr();
  731. X    sstr("Choice? ");
  732. X    while (c = gch(1), c != '1' && c != '2');
  733. X    if (c == '1')
  734. X        oneline = 1;
  735. X    else
  736. X        oneline = 0;
  737. X    cr();
  738. X    cr();
  739. X    if (!since_time)
  740. X    {
  741. X        sstrcr("List files in what order? ");
  742. X        cr();
  743. X        sstrcr("1.  Forward chronologically (old-->new)");
  744. X        sstrcr("2.  Backward chronologically (new-->old)");
  745. X        sstrcr("3.  Alphabetically ");
  746. X        sstrcr("4.  Forward chronologically from some date");
  747. X        cr();
  748. X        sstr("Choice? ");
  749. X        c = 0;
  750. X        while (c != '1' && c != '2' && c != '3' && c != '4')
  751. X            c = gch(1);
  752. X        cr();
  753. X        cr();
  754. X        switch(c)
  755. X        {
  756. X        case '1':    // forward chrono
  757. X            list_obj.sort(1);
  758. X            display_dir = 0;
  759. X            break;
  760. X        case '2':    // reverse chrono
  761. X            list_obj.sort(1);
  762. X            display_dir = 1;
  763. X            break;
  764. X        case '3': // alphabetically
  765. X            list_obj.sort(2);
  766. X            display_dir = 0;
  767. X            break;
  768. X        case '4': // forward from user entered date
  769. X            list_obj.sort(1);
  770. X            display_dir = 0;
  771. X            // get date from user
  772. X            done = 0;
  773. X            while (!done)
  774. X            {
  775. X                cr();
  776. X                sstr("Forward from what date? (mm/dd/yy) ");
  777. X                gstr(tmpstr,9);
  778. X                if (sscanf(tmpstr,"%d/%d/%d",&mon,&day,&year) == 3)
  779. X                {
  780. X                    done++;
  781. X                    time(&now);
  782. X                    tmrec = localtime(&now);
  783. X                    tmrec->tm_mday = day;
  784. X                    tmrec->tm_mon = mon-1;
  785. X                    tmrec->tm_year = year;
  786. X                    tmrec->tm_sec = 1;
  787. X                    tmrec->tm_min = 0;
  788. X                    tmrec->tm_hour = 0;
  789. X                    fromdate = mktime(tmrec);
  790. X                    since_time = fromdate;
  791. X                    list_obj.top();
  792. X                    rec = list_obj.next();
  793. X                    while (rec->date < fromdate && rec != NULL)
  794. X                        rec = list_obj.next();
  795. X                    if (rec == NULL)
  796. X                    {
  797. X                        waitcr();
  798. X                        return(0);
  799. X                    }
  800. X                    rec = list_obj.previous(); // move back one (for forward)
  801. X                }
  802. X            }
  803. X        }
  804. X    }
  805. X    else     // 'new' files only
  806. X    {
  807. X        list_obj.sort(1);
  808. X        display_dir = 0;
  809. X        list_obj.top();
  810. X        rec = list_obj.next();
  811. X        done = 0;
  812. X        while (!done)
  813. X        {
  814. X            if (rec == NULL)
  815. X            {
  816. X                done++;
  817. X                continue;
  818. X            }
  819. X            if (rec->date < since_time)
  820. X                rec = list_obj.next();
  821. X            else
  822. X                done++;
  823. X        }
  824. X        if (rec == NULL)
  825. X        {
  826. X            sstrcr("No new files found.");
  827. X            waitcr();
  828. X            return(0);
  829. X        }
  830. X        rec = list_obj.previous(); // move back one (for forward)
  831. X    }
  832. X    // Ok.  got everything we need.  Now show him the files.
  833. X    done = 0;
  834. X    if (!since_time)
  835. X        if (display_dir == 1)
  836. X            list_obj.bottom();
  837. X        else
  838. X            list_obj.top();
  839. X    numfiles = 0;
  840. X    ksel = 0;        // nothing selected (yet)
  841. X    while (!done)
  842. X    {
  843. X        x = 0;
  844. X        clear();
  845. X        numlines=0;
  846. X        sprintf(tmpstr,"Files section %s: (%d files)",long_desc,list_obj.numrecs());
  847. X        sstrcr(tmpstr);
  848. X        if (oneline)
  849. X            sstrcr(" #  Filename        Size     Date  Dl A  Short Description");
  850. X        while (x<20&&numlines<20)
  851. X        {
  852. X            if (display_dir == 1)
  853. X                rec = list_obj.previous();
  854. X            else
  855. X                rec = list_obj.next();
  856. X            flist[x] = rec;
  857. X            if (rec == NULL)
  858. X            {
  859. X                x = 20;
  860. X                continue;
  861. X            }
  862. X            if (oneline)
  863. X            {
  864. X                tmrec = localtime(&rec->date);
  865. X                strftime(datestr,11,"%x",tmrec);
  866. X                sprintf(tmpstr,"%2d. %-14.14s %6d %s %2d %c %-39.39s",x+1,
  867. X                rec->name,rec->size,datestr,rec->numdls,rec->avail,rec->sdesc);
  868. X                sstrcr(tmpstr);
  869. X            } else
  870. X            {
  871. X                sprintf(tmpstr,"%2d. ",x+1);
  872. X                sstr(tmpstr);
  873. X                numlines += info(rec,NULL,NULL);
  874. X            }
  875. X            x++;
  876. X        }
  877. X        // now give him a prompt
  878. X        cr();
  879. X        if (strcmp(user->colr,"black")==0 || strcmp(username(),sysop)==0) // sysop 
  880. X            sstr("E>dit ");
  881. X        if (can_download)
  882. X            sstr("M>ark U>nmark D>ownload ");
  883. X        sstr("I>nfo Q>uit F>orward B>ack Command? ");
  884. X        time(&then);
  885. X        inactivity = inactivity_timeout();
  886. X        while (c = tolower(gch(2)), c != 'd' && c != 'm' && c != 'i' && c !=
  887. X        'u' && c != 'q' && c != 'f' && c != 'b' && c != 'e')
  888. X        {
  889. X            time(&now);
  890. X            if ((now - then)/60 > inactivity)
  891. X            {
  892. X                return(numdownls);    
  893. X            }
  894. X        }
  895. X        cr();
  896. X        switch(c)
  897. X        {
  898. X        case 'e':
  899. X            if (strcmp(user->colr,"black")==0 || strcmp(username(),sysop)==0) // sysop 
  900. X            {
  901. X                sprintf(tmpstr,"Edit which file? (1-%d) ",x);
  902. X                sstr(tmpstr);
  903. X                gstr(tmpstr,3);
  904. X                if (sscanf(tmpstr,"%d",&off) == 1 && off > 0 && off < 21)
  905. X                {
  906. X
  907. X                    edit_file(flist[off-1]);
  908. X                }
  909. X            }
  910. X            break;
  911. X        case 'd':
  912. X            if (can_download)
  913. X            {
  914. X                if (numfiles <= 0)
  915. X                {    // do one file
  916. X                    sprintf(tmpstr,"Download which file? (1-%d) ",x);
  917. X                    sstr(tmpstr);
  918. X                    gstr(tmpstr,3);
  919. X                    if (sscanf(tmpstr,"%d",&off) == 1 && off > 0 && off <= x)
  920. X                    {
  921. X                        if (flist[off-1]->avail != 'Y')
  922. X                        {
  923. X                            sprintf(tmpstr,"File %s is not available for download.",flist[off-1]->name);
  924. X                            sstrcr(tmpstr);
  925. X                            waitcr();
  926. X                        }
  927. X                        else
  928. X                        {
  929. X                            numdownls += download(&flist[off-1],1,1);// one file
  930. X                            *kused += flist[off-1]->size/1024;
  931. X                            return(numdownls);
  932. X                        }
  933. X                    }
  934. X                }
  935. X                else
  936. X                {
  937. X                    numdownls += download(mlist,numfiles,1);// many files
  938. X                    for (x=0; x<numfiles; x++)
  939. X                        *kused += mlist[x]->size/1024;
  940. X                    numfiles = 0;
  941. X                    ksel = 0;
  942. X                    return(numdownls);
  943. X                }
  944. X            }
  945. X            else
  946. X            {
  947. X                sstrcr("You do not have download privileges for this files area.");
  948. X                waitcr();
  949. X            }
  950. X            break;
  951. X        case 'q': // exit
  952. X            if (numfiles > 0)
  953. X            {
  954. X                clear();
  955. X                sstrcr("You have marked files for download.");
  956. X                sstr("Do you want to exit without downloading? ");
  957. X                if (yesno())
  958. X                    return(0);
  959. X            }
  960. X            else
  961. X                return(0);
  962. X        case 'm': // mark a file
  963. X            if (numfiles < 19&&can_download)
  964. X            {
  965. X                if (uratio > fabs(ratio()))
  966. X                {
  967. X                    sstrcr("You have not kept your download to upload ratio");
  968. X                    sprintf(tmpstr,"within %2.1f to 1.  (%2.1f downloads are allowed for every upload)",ratio());
  969. X                    sstrcr(tmpstr);
  970. X                    sstrcr("Please upload to fix the problem.");
  971. X                    waitcr();
  972. X                    return(0);
  973. X                } 
  974. X                if (uratio <= 0 && ratio() < 0)
  975. X                {
  976. X                    sstrcr("You must upload to the BBS before you are given");
  977. X                    sstrcr("download priviledges.");
  978. X                    sstrcr("Please upload and you will have download access.");
  979. X                    waitcr();
  980. X                    return(0);
  981. X                }
  982. X                sprintf(tmpstr,"Mark which file? (1-%d) ",x);
  983. X                sstr(tmpstr);
  984. X                gstr(tmpstr,3);
  985. X                if (sscanf(tmpstr,"%d",&off) == 1 && off > 0 && off < 21)
  986. X                {
  987. X                    if (flist[off-1] != NULL)
  988. X                    {
  989. X                        if (*kused + ((flist[off-1]->size/1024)+ksel) > thisuser->kbytes && thisuser->kbytes > 0)
  990. X                        {
  991. X                            cr();
  992. X                            cr();
  993. X                            sstrcr("You do not have enough download space to download this file.");
  994. X                            sprintf(tmpstr,"You have %d K-bytes of download space every %d hours.",thisuser->kbytes,waittime());
  995. X                            sstrcr(tmpstr);
  996. X                            waitcr();
  997. X                        }
  998. X                        else if (ksel + (flist[off-1]->size/1024) > maxk())
  999. X                        {
  1000. X                            cr();
  1001. X                            cr();
  1002. X                            sprintf(tmpstr,"The BBS allows %d Kbytes of downloads for any one batch.",maxk());
  1003. X                            sstrcr(tmpstr);
  1004. X                            sstrcr("Your batch size must remain below this amount.");
  1005. X                            waitcr();
  1006. X                        }
  1007. X                        else
  1008. X                        {
  1009. X                            if (flist[off-1]->avail != 'Y')
  1010. X                            {
  1011. X                                sprintf(tmpstr,"File %s is not available for download.",flist[off-1]->name);
  1012. X                                sstrcr(tmpstr);
  1013. X                                waitcr();
  1014. X                            }
  1015. X                            else
  1016. X                            {
  1017. X                                ksel += flist[off-1]->size/1024;
  1018. X                                cr();
  1019. X                                cr();
  1020. X                                sprintf(tmpstr,"Marked %s for download.",flist[off-1]->name);
  1021. X                                sstrcr(tmpstr);
  1022. X                                waitcr();
  1023. X                                mlist[numfiles++] = flist[off-1];
  1024. X                            }
  1025. X                        }
  1026. X                    }
  1027. X                }
  1028. X            }
  1029. X            else
  1030. X            {
  1031. X                if (numfiles >= 19)
  1032. X                    sstrcr("Only 20 files may be marked for download at one time.");
  1033. X                else
  1034. X                    sstrcr("You do not have download privileges for this files area.");
  1035. X                waitcr();
  1036. X            }
  1037. X            break;
  1038. X        case 'i': // info on a file
  1039. X            sprintf(tmpstr,"Info on which file? (1-%d) ",x);
  1040. X            sstr(tmpstr);
  1041. X            gstr(tmpstr,3);
  1042. X            if (sscanf(tmpstr,"%d",&off) == 1 && off > 0 && off < 21)
  1043. X            {
  1044. X                if (flist[off-1] != NULL)
  1045. X                {
  1046. X                    info(flist[off-1],NULL,NULL);
  1047. X                    waitcr();
  1048. X                }
  1049. X            }
  1050. X            break;
  1051. X        case 'f': // move to next screen
  1052. X            continue;
  1053. X            break;
  1054. X        case 'b': // move back one screen
  1055. X            x = 0;
  1056. X            while (x<40 && rec != NULL )
  1057. X            {
  1058. X                if (display_dir == 1)
  1059. X                    rec = list_obj.next();
  1060. X                else
  1061. X                    rec = list_obj.previous();
  1062. X                x++;
  1063. X            }
  1064. X            continue;
  1065. X            break;
  1066. X        case 'u': // unmark a file
  1067. X            if (numfiles > 0)
  1068. X            {
  1069. X                cr();
  1070. X                sstrcr("Files marked for download:");
  1071. X                for (x=0; x<numfiles; x++)
  1072. X                {
  1073. X                    sprintf(tmpstr,"%d. %s",x+1,mlist[x]);
  1074. X                    sstrcr(tmpstr);
  1075. X                }
  1076. X                cr();
  1077. X                sstr("Unmark which file? ");
  1078. X                gstr(tmpstr,3);
  1079. X                if (sscanf(tmpstr,"%d",&off) == 1 && off > 0 && off < numfiles+1)
  1080. X                {
  1081. X                    sprintf(tmpstr,"File %d unmarked.",mlist[off-1]);
  1082. X                    sstrcr(tmpstr);
  1083. X                    // umark the file.  compact list
  1084. X                    t = 0;
  1085. X                    for (x=0; x<numfiles; x++)
  1086. X                        if (x != off-1)
  1087. X                            flist[x] = mlist[t++]; 
  1088. X                        else
  1089. X                            t++;
  1090. X                    // now copy back w/o file
  1091. X                    for (x=0; x<numfiles-1; x++)
  1092. X                        mlist[x] = flist[x];
  1093. X                    numfiles--;
  1094. X                    waitcr();
  1095. X                }
  1096. X            }
  1097. X        }
  1098. X        // go back so that 'next' batch is right
  1099. X        while (x>-1 && rec != NULL)
  1100. X        {
  1101. X            if (display_dir != 1)
  1102. X                rec = list_obj.previous();
  1103. X            else
  1104. X                rec = list_obj.next();
  1105. X            x--;
  1106. X        }
  1107. X    }
  1108. X    return(numdownls);
  1109. X};
  1110. X// Function:    one_download
  1111. X// Purpose:    get a filename from the user and download that file
  1112. X// Input:    none
  1113. X// Output:    if the file name is found, the file will be downloaded
  1114. X// Author:    Greg Shaw
  1115. X// Created:    8/10/93
  1116. X
  1117. Xint files::one_download(int *kused, float uratio, char *filename, int counts)
  1118. X{
  1119. X    char    str[50];
  1120. X    char    tmpstr[20];
  1121. X    FInfo    *rec,tmprec;
  1122. X
  1123. X    // get filename
  1124. X    clear();
  1125. X    if (filename != NULL)
  1126. X    {
  1127. X        // create a dummy record for this download
  1128. X        strcpy(tmprec.name,filename);
  1129. X        tmprec.avail = 'Y';
  1130. X        tmprec.numdls = 0;
  1131. X        tmprec.size = 0;
  1132. X        rec = &tmprec;
  1133. X    }
  1134. X    else
  1135. X    {
  1136. X        sstrcr("Note: case matters");
  1137. X        cr();
  1138. X        sstr("Download which file? (q to quit) ");
  1139. X        gstr(tmpstr,MAX_FILENAMELENGTH);
  1140. X        if (strcmp(tmpstr,"q") == 0)
  1141. X            return(0);
  1142. X        cr();
  1143. X        // now find the file in the list
  1144. X        list_obj.top();    
  1145. X        rec = list_obj.next();
  1146. X        while (strcmp(rec->name,tmpstr) != 0 && rec != NULL)
  1147. X            rec = list_obj.next();
  1148. X        if (rec == NULL)
  1149. X        {
  1150. X            sprintf(str,"Unable to find a file named %s.",tmpstr);
  1151. X            sstrcr(str);
  1152. X            waitcr();
  1153. X            return(0);
  1154. X        }
  1155. X        if (rec->avail == 'N')
  1156. X        {
  1157. X            sprintf(str,"File %s is not available for download.",rec->name);
  1158. X            sstrcr(str);
  1159. X            waitcr();
  1160. X            return(0);
  1161. X        }
  1162. X    }
  1163. X    // download the beastie!
  1164. X    if (counts) // does this count to upload/download ratios?
  1165. X    {
  1166. X        if (*kused + ((rec->size/1024)+ksel) > thisuser->kbytes && thisuser->kbytes > 0)
  1167. X        {
  1168. X            cr();
  1169. X            cr();
  1170. X            sstrcr("You do not have enough download space to download this file.");
  1171. X            sprintf(tmpstr,"You have %d K-bytes of download space every %d hours.",thisuser->kbytes,waittime());
  1172. X            sstrcr(tmpstr);
  1173. X            waitcr();
  1174. X            return(0);
  1175. X        }
  1176. X        if (uratio > fabs(ratio()))
  1177. X        {
  1178. X            sstrcr("You have not kept your download to upload ratio");
  1179. X            sprintf(tmpstr,"within %2.1f to 1.  (%2.1f downloads are allowed for every upload)",ratio());
  1180. X            sstrcr(tmpstr);
  1181. X            sstrcr("Please upload to fix the problem.");
  1182. X            waitcr();
  1183. X            return(0);
  1184. X        } 
  1185. X        if (uratio <= 0 && ratio() < 0)
  1186. X        {
  1187. X            sstrcr("You must upload to the BBS before you are given");
  1188. X            sstrcr("download priviledges.");
  1189. X            sstrcr("Please upload and you will have download access.");
  1190. X            waitcr();
  1191. X            return(0);
  1192. X        }
  1193. X    }
  1194. X    download(&rec,1,counts);
  1195. X    return(1);
  1196. X};
  1197. X
  1198. X// Function:    open
  1199. X// Purpose:    open the files section.  
  1200. X// Input:    path - the name of the bbs section to read
  1201. X// Output:    none.  setup function only.
  1202. X// Author:    Greg Shaw
  1203. X// Created:    8/1/93
  1204. X
  1205. Xint files::open(char *sname, CardRec *user)
  1206. X{
  1207. X    FILE    *infile;
  1208. X    struct stat fistat;    // file status record
  1209. X    FInfo    newrec;            // record for insert into list
  1210. X    char    word[50];
  1211. X    char    tmpstr[255];
  1212. X    char    tmpstr2[255];
  1213. X    char    tmpstr3[255];
  1214. X    int    off;
  1215. X    int    line;
  1216. X    int    found;
  1217. X    char     *u;    // used for erasing right bracket
  1218. X    char     *bbsdir;// used for bbsdir environment var
  1219. X    char    c;
  1220. X
  1221. X    thisuser = user;
  1222. X    bbsdir = getenv("BBSDIR");     // not checking because he shouldn't
  1223. X    if (strcmp(sname,name) != 0)    // don't open if already open
  1224. X    {
  1225. X        list_obj.clear_list();        // nuke old values
  1226. X        strcpy(tmpstr,getenv("BBSDIR"));     // not checking because he shouldn't
  1227. X                        // get here if bbsdir not set
  1228. X        strcat(tmpstr,"/filehdr/bbs_files_hdr");    // tack on files header
  1229. X        if (infile = bopen(tmpstr,"r"), infile == NULL)
  1230. X        {
  1231. X            sprintf(tmpstr,"Unable to open main files section header (bbs_files_hdr)",name);
  1232. X            ap_log(tmpstr);
  1233. X            return(-1);
  1234. X        }
  1235. X        // ok.  got file.  let's find the line we're looking for
  1236. X        found = 0;
  1237. X        while (!found && !feof(infile))
  1238. X        {
  1239. X            // look for left bracket
  1240. X            while (c = fgetc(infile), c != '[' && !feof(infile));
  1241. X            // now get the rest of the line
  1242. X            if (fscanf(infile,"%s %s %d %s %s %d%50s",name,sysop,&acl,dn_path,
  1243. X                up_path, &age, long_desc) != 7)
  1244. X            {
  1245. X                sprintf(tmpstr,"Unable to find %s in bbs main files header.",sname);
  1246. X                ap_log(tmpstr);
  1247. X                return(-1);
  1248. X            }
  1249. X            while (fscanf(infile,"%s",word) == 1 && strchr(word,']') == NULL)
  1250. X            {
  1251. X                strcat(long_desc," ");
  1252. X                strcat(long_desc,word);
  1253. X            }
  1254. X            if (u = strchr(long_desc,']'), u != NULL)
  1255. X                u[0] = 0;    // turn into null
  1256. X            if (strcmp(name,sname) == 0)
  1257. X                found++;    // gotcha
  1258. X        }
  1259. X        bclose(infile);    
  1260. X        strcpy(tmpstr,getenv("BBSDIR"));// not checking because he shouldn't make it this far
  1261. X        strcat(tmpstr,"/filehdr/");    // get name of file area
  1262. X        strcat(tmpstr,name);
  1263. X        if (infile = bopen(tmpstr,"r"),infile  == NULL)
  1264. X        {
  1265. X            // empty files section
  1266. X            return(0);
  1267. X        }
  1268. X        // ok.  now read everything into dllist object
  1269. X        line = 0;
  1270. X        while (!feof(infile))
  1271. X        {
  1272. X            while (c=fgetc(infile), c != '[' && !feof(infile));
  1273. X            if (feof(infile))
  1274. X                continue;
  1275. X            switch(line)
  1276. X            {
  1277. X            case 0:    // line 1
  1278. X                if (c = fgetc(infile), c == 'A')
  1279. X                {
  1280. X                    tmpstr2[0] = 0;
  1281. X                    tmpstr3[0] = 0;
  1282. X                    fscanf(infile,"%s %d %s",newrec.uploader,
  1283. X                    &newrec.numdls,newrec.name,tmpstr2,tmpstr3);
  1284. X                    if (strlen(tmpstr2) > 0 && tmpstr2[0] != ']')
  1285. X                    {
  1286. X                        sprintf(tmpstr,"%s %s",newrec.name,tmpstr2);
  1287. X                        strcpy(newrec.name,tmpstr);
  1288. X                    }
  1289. X                    if (strlen(tmpstr3) > 0 && tmpstr3[0] != ']')
  1290. X                    {
  1291. X                        sprintf(tmpstr,"%s %s",newrec.name,tmpstr3);
  1292. X                        strcpy(newrec.name,tmpstr);
  1293. X                    }
  1294. X
  1295. X                    sprintf(tmpstr,"%s/files/%s/%s",bbsdir,dn_path,newrec.name);
  1296. X                    if (stat(tmpstr,&fistat) == 0 && S_ISREG(fistat.st_mode))
  1297. X                    {
  1298. X                        newrec.size = fistat.st_size;
  1299. X                        newrec.date = fistat.st_ctime;
  1300. X                        newrec.avail = 'Y';
  1301. X                    }
  1302. X                    else
  1303. X                    {
  1304. X                        newrec.size = 0;
  1305. X                        newrec.date = 0;
  1306. X                        newrec.avail = 'N';
  1307. X                    }
  1308. X                    line++;
  1309. X                }
  1310. X                break;
  1311. X            case 1:    // line 2
  1312. X                if (c = fgetc(infile), c == 'B')
  1313. X                {
  1314. X                    off = 0;
  1315. X                    while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile))
  1316. X                        tmpstr[off++] = c;
  1317. X                    tmpstr[off] = 0;
  1318. X                    strcpy(newrec.sdesc,tmpstr);
  1319. X                    if (u = strchr(newrec.sdesc,']'), u != NULL)
  1320. X                        u[0] = 0;    // turn into null
  1321. X                    if (strcmp(newrec.sdesc," ") == 0)
  1322. X                        strcpy(newrec.sdesc,"none");
  1323. X                    line++;
  1324. X                }
  1325. X                break;
  1326. X            case 2:    // line 3
  1327. X                if (c = fgetc(infile), c == 'C')
  1328. X                {
  1329. X                    newrec.filepos = ftell(infile);
  1330. X                    list_obj.add(&newrec);
  1331. X                    fscanf(infile,"%s",tmpstr);
  1332. X                    line++;
  1333. X                }
  1334. X                break;
  1335. X            case 3:    // line 4
  1336. X                if (c = fgetc(infile), c == 'D')
  1337. X                {
  1338. X                    fscanf(infile,"%s",tmpstr);
  1339. X                    line++;
  1340. X                }
  1341. X                break;
  1342. X            case 4:    // line 5
  1343. X                if (c = fgetc(infile), c == 'E')
  1344. X                {
  1345. X                    fscanf(infile,"%s",tmpstr);
  1346. X                    line++;
  1347. X                }
  1348. X                break;
  1349. X            case 5:    // line 6
  1350. X                if (c = fgetc(infile), c == 'F')
  1351. X                {
  1352. X                    fscanf(infile,"%s",tmpstr);
  1353. X                    line = 0;
  1354. X                }
  1355. X                break;
  1356. X            }
  1357. X        }
  1358. X        bclose(infile);
  1359. X    }
  1360. X    return(0);
  1361. X};
  1362. X
  1363. X// Function:    update_information
  1364. X// Purpose:    update the file information in the header file
  1365. X// Input:    list - the information for the file
  1366. X// Output:    none
  1367. X// Author:    Greg Shaw
  1368. X// Created:    8/10/93
  1369. X
  1370. Xint files::update_information(FInfo *item, char *origname, char desc[3][100], char *machreq, int del)
  1371. X{
  1372. X    FILE    *infile;
  1373. X    FILE    *outfile;
  1374. X    int    off;
  1375. X    char    line[150];
  1376. X    char    tmpstr[255];
  1377. X    char    fname[MAX_FILENAMELENGTH+1];
  1378. X    char    c;
  1379. X    
  1380. X    printf("opening files...\n");
  1381. X    fflush(stdout);
  1382. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  1383. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  1384. X    {
  1385. X        sprintf(tmpstr,"Unable to open %s for read.",name);
  1386. X        ap_log(tmpstr);
  1387. X        return(0);
  1388. X    }
  1389. X    sprintf(tmpstr,"%s/filehdr/%s.new",getenv("BBSDIR"),name);
  1390. X    if (outfile = bopen(tmpstr,"w"), outfile == NULL)
  1391. X    {
  1392. X        sprintf(tmpstr,"Unable to open %s.new for write.",name);
  1393. X        ap_log(tmpstr);
  1394. X        return(0);
  1395. X    }
  1396. X    printf("start of loop...\n");
  1397. X    fflush(stdout);
  1398. X    while (!feof(infile))
  1399. X    {
  1400. X        off = 0;
  1401. X        while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile))    
  1402. X            line[off++] = c;
  1403. X        line[off] = 0;
  1404. X        if (line[0] == '[' && line[1] == 'A')    // first line?
  1405. X        {
  1406. X            if (!sscanf(&line[2],"%s %*ld %*ld %*d %*s", fname))
  1407. X            {
  1408. X                sprintf(tmpstr,"Error found in files listing %s for file %s",name,fname);
  1409. X                ap_log(tmpstr);        
  1410. X            }
  1411. X            if (strcmp(fname,origname) == 0 )
  1412. X            {
  1413. X    printf("found target...\n");
  1414. X    fflush(stdout);
  1415. X                if (del)
  1416. X                {
  1417. X                    sprintf(tmpstr,"%s/files/%s/%s",getenv("BBSDIR"),
  1418. X                        dn_path, item->name);
  1419. X                    if (unlink(tmpstr))
  1420. X                    {
  1421. X                        sprintf(tmpstr,"Unable to delete file %s",item->name);
  1422. X                        ap_log(tmpstr);
  1423. X                    }
  1424. X                    // skip next 5 lines
  1425. X                    off=0;
  1426. X                    while (off < 5)
  1427. X                    {
  1428. X                        if (c = fgetc(infile), c == '\r' || c == '\n')
  1429. X                            off++;
  1430. X                    }
  1431. X                }
  1432. X                fprintf(outfile,"[A %s %d %s ]\n",item->uploader, item->numdls, item->name);
  1433. X                fprintf(outfile,"[B %s ]\n",item->sdesc);
  1434. X                fprintf(outfile,"[C %s ]\n",machreq);
  1435. X                fprintf(outfile,"[D %s ]\n",desc[0]);
  1436. X                fprintf(outfile,"[E %s ]\n",desc[1]);
  1437. X                fprintf(outfile,"[F %s ]\n",desc[2]);
  1438. X                // skip next 5 lines
  1439. X                off=0;
  1440. X                while (off < 5)
  1441. X                {
  1442. X                    if (c = fgetc(infile), c == '\r' || c == '\n')
  1443. X                        off++;
  1444. X                }
  1445. X                while (!feof(infile))
  1446. X                    if (c = fgetc(infile), c != EOF)
  1447. X                        fputc(c,outfile);
  1448. X            }
  1449. X            else
  1450. X                fprintf(outfile,"%s\n",line);
  1451. X        }
  1452. X        else if (strcmp(line,"") != 0)
  1453. X            fprintf(outfile,"%s\n",line);
  1454. X    }
  1455. X    printf("exit loop...\n");
  1456. X    fflush(stdout);
  1457. X    bclose(infile);
  1458. X    bclose(outfile);
  1459. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  1460. X    sprintf(line,"%s/filehdr/%s.old",getenv("BBSDIR"),name);
  1461. X    rename(tmpstr,line);    // rename file
  1462. X    sprintf(tmpstr,"%s/filehdr/%s.new",getenv("BBSDIR"),name);
  1463. X    sprintf(line,"%s/filehdr/%s",getenv("BBSDIR"),name);
  1464. X    rename(tmpstr,line);    // rename file
  1465. X    sprintf(tmpstr,"%s/filehdr/%s",getenv("BBSDIR"),name);
  1466. X    chmod(tmpstr,0775);
  1467. X    chown(tmpstr,bbs_uid(),bbs_gid());    // change owner to bbs
  1468. X    return(0);
  1469. X};
  1470. X
  1471. X
  1472. X// Function:    search
  1473. X// Purpose:    search for a file in the files section
  1474. X// Input:    can_download - can the user download the file if he wants
  1475. X// Output:    if the search is successfull, the file will be displayed to the user
  1476. X//        bbs directory upload directory (or wherever the uploaddir is)
  1477. X// Author:     Greg Shaw
  1478. X// Created:    8/9/93
  1479. X
  1480. Xint files::search(int can_download)
  1481. X{
  1482. X    char    fname[MAX_FILENAMELENGTH+1];    // filename to search for
  1483. X    FInfo    *rec;
  1484. X    clear();
  1485. X    sstrcr("Enter any substring to search for.");
  1486. X    cr();
  1487. X    sstr("Search for what string? ");
  1488. X    gstr(fname,MAX_FILENAMELENGTH); 
  1489. X    if (fname[0] == 0)
  1490. X        return(0);
  1491. X    list_obj.top();
  1492. X    while (rec = list_obj.next(), rec != NULL)
  1493. X    {
  1494. X        if (strstr(rec->name,fname) != NULL)
  1495. X        {
  1496. X            info(rec,NULL,NULL);
  1497. X            waitcr();
  1498. X            if (can_download)
  1499. X            {
  1500. X                cr();
  1501. X                sstr("Download this file? ");
  1502. X                if (yesno())
  1503. X                    download(&rec,1,1);
  1504. X            }
  1505. X            sstr("Continue with search? ");
  1506. X            if (!yesno())
  1507. X                break;
  1508. X        }
  1509. X    }    
  1510. X    cr();
  1511. X    sstrcr("No more files found.");
  1512. X    waitcr();
  1513. X    return(0);
  1514. X};
  1515. X
  1516. X// Function:    upload
  1517. X// Purpose:    upload file(s) to the BBS
  1518. X// Input:    name - name of user (for temp directory name)
  1519. X// Output:    if the file upload is successful, it will be moved to the 
  1520. X//        bbs directory upload directory (or wherever the uploaddir is)
  1521. X// Author:     Greg Shaw
  1522. X// Created:    8/9/93
  1523. X
  1524. Xint files::upload(char *uname, char *editor, int *credminutes)
  1525. X{
  1526. X    DIR    *fdir;        // directory file descriptor
  1527. X    struct dirent *dentry;    // directory entry
  1528. X    struct stat fistat;    // file status record
  1529. X    time_t    now;        // upload date
  1530. X    time_t    start;        // start of upload time 
  1531. X    time_t    end;        // end of upload time
  1532. X    FILE    *outfile;    // protocols file
  1533. X    FILE    *infile;    // protocols file
  1534. X    int    off;        // offset into line
  1535. X    int    x;
  1536. X    int    numuploads;    // number of files uploaded
  1537. X    int    numprot;    // number of 'real' protocols
  1538. X    int    protsel;    // index of selected protocol
  1539. X    int    done;        // loop boolean
  1540. X    int    linenum;    // line number
  1541. X    char    c;        // one char from file
  1542. X    char    tmpstr[255];    // temp str 
  1543. X    char    tmpstr2[255];    // temp str 
  1544. X    char    bbsdir[255];    // temp str 
  1545. X    char    comm[MAX_DL_COMMANDS][50];    // 15 commands max
  1546. X    char    key[MAX_DL_COMMANDS];    // key for selecting command
  1547. X    char    needs_filename[MAX_DL_COMMANDS];// key for selecting command
  1548. X    char    filename[MAX_FILENAMELENGTH];    // filename
  1549. X    char    text[MAX_DL_COMMANDS][50];    // text describing command
  1550. X    char    line[255];
  1551. X
  1552. X    time(&start);
  1553. X    numuploads = 0;
  1554. X    strcpy(bbsdir,getenv("BBSDIR"));     // not checking error
  1555. X    strcpy(tmpstr,bbsdir);
  1556. X    strcat(tmpstr,"/config/protocols");
  1557. X    // read protocols file.  digest.  display options to user.
  1558. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  1559. X    {
  1560. X        ap_log("Unable to open config/protocols file.");
  1561. X        return(0);
  1562. X    }
  1563. X    // now read protocols file.
  1564. X    numprot = 0;
  1565. X    while (!feof(infile))
  1566. X    {
  1567. X        off = 0;
  1568. X        while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  1569. X            line[off++] = c;
  1570. X        // now digest line
  1571. X        line[off] = 0;        // add null (for posterity) (and possibly anterity)
  1572. X        if (off < 5 || feof(infile))    // line can't be less than 5 chars long
  1573. X            continue;
  1574. X        if (line[0] == 'U')    // we care about upload only
  1575. X        {
  1576. X            // get command
  1577. X            // note: this is pretty nasty.  Beer (good) and programming
  1578. X            // are not necessarily mutually exclusive. 
  1579. X            // although beer and excellent programming may be.
  1580. X            off = 2;
  1581. X            while (line[off] != '|' && line[off] != 0)
  1582. X            {
  1583. X                comm[numprot][off-2] = line[off++];
  1584. X            }
  1585. X            comm[numprot][off-2] = 0;    // add null
  1586. X            off++;    // skip |    
  1587. X            needs_filename[numprot] = line[off++];    // get 'needs filename' information
  1588. X            off++;    // skip |    
  1589. X            key[numprot] = line[off++];    // get hot key
  1590. X            off++;    // skip |    
  1591. X            x = off;    // give an offset
  1592. X            while (line[off] != 0)
  1593. X                text[numprot][off - x] = line[off++];
  1594. X            text[numprot++][off-x] = 0;
  1595. X        }
  1596. X    }
  1597. X    bclose(infile);
  1598. X    // now show the bastich the protcols and let him choose...
  1599. X    cr();
  1600. X    sstrcr("Select Upload Protocol: (or q to quit) ");
  1601. X    cr();
  1602. X    for (x=0; x<numprot; x++)
  1603. X        sstrcr(text[x]);
  1604. X    cr();
  1605. X    sstr("Your choice? ");
  1606. X    done = 0;
  1607. X    while (!done)
  1608. X    {
  1609. X        c = gch(1);
  1610. X        if (c == 'q')
  1611. X            return(0);
  1612. X        for (x=0; x<numprot; x++)
  1613. X            if (key[x] == c)
  1614. X            {
  1615. X                done++;
  1616. X                protsel = x;
  1617. X            }
  1618. X    }    
  1619. X    // Got protocol.  Now create temp directory.
  1620. X    strcpy(tmpstr,bbsdir);
  1621. X    strcat(tmpstr,"/tmp/");        // bbsdir/tmp
  1622. X    strcat(tmpstr,uname);    // bbsdir/tmp/username
  1623. X    if (mkdir(tmpstr,(S_IRUSR | S_IWUSR | S_IXUSR)) != 0 && errno != EEXIST)
  1624. X    {
  1625. X        sprintf(tmpstr,"Unable to create %s/tmp/%s",bbsdir,uname);
  1626. X        ap_log(tmpstr);
  1627. X        return(-1);
  1628. X    }
  1629. X    // Ok.  Change current working directory to new directory
  1630. X    chdir(tmpstr);    // change to new directory
  1631. X    if (needs_filename[protsel] == 'y')
  1632. X    {
  1633. X        cr();
  1634. X        cr();
  1635. X        sstrcr("Enter 'q' to exit.");
  1636. X        sstr("Please enter the filename: ");
  1637. X        gstr(filename,MAX_FILENAMELENGTH);
  1638. X        fflush(stdout);
  1639. X        if (strcmp(filename,"q") == 0)
  1640. X        {
  1641. X            sstrcr("Upload aborted.");
  1642. X            waitcr();
  1643. X            return(0);
  1644. X        }
  1645. X    }
  1646. X    cr();
  1647. X    cr();
  1648. X    sstrcr("Ready to start upload.");
  1649. X    cr();
  1650. X    strcpy(tmpstr,comm[protsel]);
  1651. X    if (needs_filename[protsel] == 'y')
  1652. X    {
  1653. X        strcat(tmpstr," ");
  1654. X        strcat(tmpstr,filename);
  1655. X    }
  1656. X    // ok.  pass to system
  1657. X    waitcr();
  1658. X    sysint(tmpstr);
  1659. X    clear();
  1660. X    cr();
  1661. X    cr();
  1662. X    sstr("Was the upload successful? ");
  1663. X    if (!yesno())
  1664. X    {
  1665. X        sstr("Would you like to save your transfer to resume later? ");
  1666. X        if (!yesno())
  1667. X        {
  1668. X            sprintf(tmpstr,"rm -rf %s/tmp/%s",bbsdir,uname);
  1669. X            sysint(tmpstr);
  1670. X        }
  1671. X        return(0);
  1672. X    }
  1673. X    // now look at directory and get filename(s) that were uploaded
  1674. X    time(&now);
  1675. X    strcpy(tmpstr,bbsdir);
  1676. X    strcat(tmpstr,"/filehdr/");    // tack on files header
  1677. X    strcat(tmpstr,name);
  1678. X    if (outfile = bopen(tmpstr,"a"), outfile == NULL)
  1679. X    {
  1680. X        sprintf(tmpstr,"Unable to open files section header %s",name);
  1681. X        ap_log(tmpstr);
  1682. X        return(0);
  1683. X    }
  1684. X    strcpy(tmpstr,bbsdir);
  1685. X    strcat(tmpstr,"/tmp/");
  1686. X    strcat(tmpstr,uname);
  1687. X    if (fdir = opendir(tmpstr), fdir == NULL)
  1688. X    {
  1689. X        sprintf(line,"Unable to open directory %s for reading.\n",tmpstr);
  1690. X        bclose(outfile);
  1691. X        ap_log(line);
  1692. X        return(0);
  1693. X    }
  1694. X    // ok.  now loop for every file found, getting file information
  1695. X    while (dentry = readdir(fdir), dentry != NULL)
  1696. X    {
  1697. X        strcpy(tmpstr,bbsdir);
  1698. X        strcat(tmpstr,"/tmp/");
  1699. X        strcat(tmpstr,uname);
  1700. X        strcat(tmpstr,"/");
  1701. X        strcat(tmpstr,dentry->d_name);    // for stat
  1702. X        if (stat(tmpstr,&fistat) == 0 && S_ISREG(fistat.st_mode))
  1703. X        {
  1704. X            sprintf(tmpstr,"Was file %s uploaded correctly? ",dentry->d_name);
  1705. X            sstr(tmpstr);
  1706. X            if (!yesno())
  1707. X                continue;    // skip bad file upload
  1708. X            fprintf(outfile,"[A %s 0 %s ]\n",uname, dentry->d_name);
  1709. X            sprintf(tmpstr,"Entering information for file %s.",dentry->d_name);
  1710. X            sstrcr(tmpstr);
  1711. X            cr();
  1712. X            sstrcr("Please enter a short (less than 40 characters) description for the file. ");
  1713. X            sstr(": ");
  1714. X            gstr(tmpstr,40);
  1715. X            fprintf(outfile,"[B %s ]\n",tmpstr);
  1716. X            // get machine requirements
  1717. X            cr();
  1718. X            sstrcr("Please enter the software/hardware requirements ");
  1719. X            sprintf(tmpstr,"for file %s: ",dentry->d_name);
  1720. X            sstr(tmpstr);
  1721. X            gstr(tmpstr,40);
  1722. X            fprintf(outfile,"[C %s ]\n",tmpstr);
  1723. X            // now get the long description
  1724. X            // create temp file
  1725. X            strcpy(tmpstr,"bbsXXXXXX");
  1726. X            mktemp(tmpstr);
  1727. X            if (tmpstr[0] == 0)
  1728. X            {
  1729. X                ap_log("Unable to create temp file for upload long description entry.");
  1730. X                fprintf(outfile,"[D ]\n");
  1731. X                fprintf(outfile,"[E ]\n");
  1732. X                fprintf(outfile,"[F ]\n");
  1733. X                continue;
  1734. X            }
  1735. X            // got temp file.  pass to system.
  1736. X            cr();
  1737. X            cr();
  1738. X            sstrcr("Now enter the long description for the file.");
  1739. X            sstrcr("I will pass you to your editor.  Please enter up to 3 ");
  1740. X            sstrcr("lines of text (80 columns per line).");
  1741. X            sstrcr("Note: Anything more than 3 lines will be ignored.");
  1742. X
  1743. X            waitcr();
  1744. X            strcpy(filename,tmpstr);
  1745. X            strcpy(tmpstr,editor);
  1746. X            strcat(tmpstr," /tmp/");
  1747. X            strcat(tmpstr,filename);
  1748. X            sysint(tmpstr);
  1749. X            strcpy(tmpstr,"/tmp/");
  1750. X            strcat(tmpstr,filename);    // now open file
  1751. X            if (infile = bopen(tmpstr,"r"), infile == NULL)
  1752. X            {
  1753. X                fprintf(outfile,"[D ]\n");
  1754. X                fprintf(outfile,"[E ]\n");
  1755. X                fprintf(outfile,"[F ]\n");
  1756. X                continue;
  1757. X            }
  1758. X            // now digest file
  1759. X            linenum = 0;
  1760. X            off = 0;
  1761. X            line[0] = 0;
  1762. X            while (!feof(infile))
  1763. X            {
  1764. X                while (c = fgetc(infile), c != '\r' && c != '\n' && !feof(infile))
  1765. X                    line[off++] = c;
  1766. X                line[off] = 0;
  1767. X                linenum++;
  1768. X                switch(linenum)
  1769. X                {
  1770. X                case 1:     
  1771. X                    fprintf(outfile,"[D %s ]\n",line);
  1772. X                    off = 0;
  1773. X                    break;
  1774. X                case 2:     
  1775. X                    fprintf(outfile,"[E %s ]\n",line);
  1776. X                    off = 0;
  1777. X                    break;
  1778. X                case 3:     
  1779. X                    fprintf(outfile,"[F %s ]\n",line);
  1780. X                    off = 0;
  1781. X                }
  1782. X            }
  1783. X            if (linenum < 3)    // got all 3 lines?
  1784. X            {
  1785. X                if (linenum == 0)    // no lines
  1786. X                {
  1787. X                    fprintf(outfile,"[D %s ]\n",line);
  1788. X                    fprintf(outfile,"[E ]\n");
  1789. X                    fprintf(outfile,"[F ]\n");
  1790. X                }
  1791. X                else if (linenum == 1)    // one line
  1792. X                {
  1793. X                    fprintf(outfile,"[E %s ]\n",line);
  1794. X                    fprintf(outfile,"[F ]\n");
  1795. X                }
  1796. X                else if (linenum == 2)    // two lines
  1797. X                    fprintf(outfile,"[F %s ]\n",line);
  1798. X            }
  1799. X            bclose(infile);
  1800. X            // now move file to uploads area
  1801. X            sprintf(tmpstr,"%s/tmp/%s/%s",bbsdir,uname,dentry->d_name);
  1802. X            sprintf(line,"%s/%s/%s",bbsdir,up_path,dentry->d_name);
  1803. X            if (rename(tmpstr,line))
  1804. X            {
  1805. X                sprintf(tmpstr2,"Unable to move %s to %s",tmpstr,line);
  1806. X                ap_log(tmpstr2);
  1807. X            }
  1808. X            sprintf(tmpstr,"/tmp/%s",filename);
  1809. X            unlink(tmpstr);    // remove temp file
  1810. X            numuploads++;
  1811. X            sprintf(tmpstr,"%s uploaded %s to %s",uname,dentry->d_name,name);
  1812. X            ap_log(tmpstr);
  1813. X        }
  1814. X    }
  1815. X    bclose(outfile);
  1816. X    closedir(fdir);
  1817. X    sprintf(tmpstr,"%s",bbsdir);
  1818. X    chdir(tmpstr);    // change to bbs root directory
  1819. X    sprintf(tmpstr,"%s/filehdr/%s",bbsdir,name);
  1820. X    chmod(tmpstr,0775);    // chmod 775
  1821. X    chown(tmpstr,bbs_uid(),bbs_gid());    // change owner to bbs
  1822. X    sprintf(tmpstr,"%s/tmp/%s",bbsdir,uname);
  1823. X    chmod(tmpstr,0775);    // chmod 775
  1824. X    chown(tmpstr,bbs_uid(),bbs_gid());    // change owner to bbs
  1825. X    sprintf(tmpstr,"%s/tmp/%s/* 2> /dev/null",bbsdir,uname);
  1826. X    unlink(tmpstr);    // remove any leftover files
  1827. X    sprintf(tmpstr,"%s/tmp/%s 2> /dev/null",bbsdir,uname);
  1828. X    rmdir(tmpstr);    // remove upload directory
  1829. X    cr();
  1830. X    sstrcr("End of upload.");
  1831. X    cr();
  1832. X    sstrcr("The file(s) have been moved to the upload directory.");
  1833. X    sstrcr("After being reviewed, they will be available for download.");
  1834. X    waitcr();
  1835. X    time(&end);
  1836. X    *credminutes = (end - start)/60;    
  1837. X    return(numuploads);
  1838. X};
  1839. X
  1840. X
  1841. X
  1842. X#endif // _FILES_C_
  1843. END_OF_FILE
  1844.   if test 47604 -ne `wc -c <'rocat-0.75/src/files.C'`; then
  1845.     echo shar: \"'rocat-0.75/src/files.C'\" unpacked with wrong size!
  1846.   fi
  1847.   chmod +x 'rocat-0.75/src/files.C'
  1848.   # end of 'rocat-0.75/src/files.C'
  1849. fi
  1850. if test -f 'rocat-0.75/src/user.C' -a "${1}" != "-c" ; then 
  1851.   echo shar: Will not clobber existing file \"'rocat-0.75/src/user.C'\"
  1852. else
  1853.   echo shar: Extracting \"'rocat-0.75/src/user.C'\" \(45033 characters\)
  1854.   sed "s/^X//" >'rocat-0.75/src/user.C' <<'END_OF_FILE'
  1855. X// Filename:     User.c
  1856. X// Contents:    the methods for the User object
  1857. X// Author:        Greg Shaw
  1858. X// Created:        6/1/93
  1859. X
  1860. X/*
  1861. XThis file is free software; you can redistribute it and/or modify it
  1862. Xunder the terms of the GNU General Public License as published by the
  1863. XFree Software Foundation; either version 2, or (at your option) any
  1864. Xlater version.
  1865. X
  1866. XIn addition to the permissions in the GNU General Public License, the
  1867. XFree Software Foundation gives you unlimited permission to link the
  1868. Xcompiled version of this file with other programs, and to distribute
  1869. Xthose programs without any restriction coming from the use of this
  1870. Xfile.  (The General Public License restrictions do apply in other
  1871. Xrespects; for example, they cover modification of the file, and
  1872. Xdistribution when not linked into another program.)
  1873. X
  1874. XThis file is distributed in the hope that it will be useful, but
  1875. XWITHOUT ANY WARRANTY; without even the implied warranty of
  1876. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  1877. XGeneral Public License for more details.
  1878. X
  1879. XYou should have received a copy of the GNU General Public License
  1880. Xalong with this program; see the file COPYING.  If not, write to
  1881. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1882. X
  1883. X#ifndef _USER_C_
  1884. X#define _USER_C_
  1885. X
  1886. X#include "bbshdr.h"
  1887. X
  1888. X// Function:    append
  1889. X// Purpose:    append a new user record to the user file
  1890. X// Input:    object attributes
  1891. X// Output:    (file is written)
  1892. X// Author:    Greg Shaw
  1893. X// Created:    7/20/93
  1894. X
  1895. Xint User::append(void)
  1896. X{
  1897. X    FILE    *ofile;
  1898. X    char    finame[255];        // filename
  1899. X    char    line[255];        // one line in file (255 max)
  1900. X    char    bbspath[225];    // bbs path
  1901. X
  1902. X    if (strcpy(bbspath,getenv("BBSDIR")), bbspath == NULL)
  1903. X    {
  1904. X        sprintf(finame,"user.save: BBSDIR env var not set for %s",login_name);
  1905. X        ap_log(finame);
  1906. X        return(-1);
  1907. X    }
  1908. X    strcpy(line,bbspath);
  1909. X    strcat(line,"/admin/userlog");
  1910. X    if (ofile = bopen(line,"a"), ofile == NULL)
  1911. X    {
  1912. X        sprintf(line,"user.save: Unable to open userlog file ");
  1913. X        ap_log(line);
  1914. X        return(-1);
  1915. X    }    
  1916. X    //[A login_name firstname lastname state city]
  1917. X    fprintf(ofile,"[A %s %s %s %s %s %s ]\n", login_name, fname, lname, alias, state, city);
  1918. X    //[B terminal_type last_logon #_logins downloads uploads card_color]
  1919. X    fprintf(ofile,"[B %s %ld %d %d %d %s ]\n", uterm, 
  1920. X        last_login, logins, downloads, uploads, card->colr);
  1921. X    //[C private_msgs public_msgs credited_time has_color editor lines cols]
  1922. X    fprintf(ofile,"[C %d %d %d %d %s %d %d ]\n",priv_msgs,pub_msgs,
  1923. X        credited, has_color, editor, lines, cols);
  1924. X    //[D flags access_level timelimit timeused_last_call anniversary kused ]
  1925. X    fprintf(ofile,"[D %lx %d %d %d %ld %d ]\n",flags, acl, timelimit, timeused, anniversary, kused);
  1926. X    bclose(ofile);
  1927. X    return(0);
  1928. X};
  1929. X
  1930. X// Function:    change_acl
  1931. X// Purpose:        change the user's access level (possibly permanently)
  1932. X// Input:        acl - the timlit to change to
  1933. X//                perm - permanent or not 
  1934. X// Output:        none
  1935. X// Author:        Greg Shaw
  1936. X// Created:        6/8/93
  1937. X
  1938. Xint User::change_acl(int acl, char perm)
  1939. X{
  1940. X    if (perm)
  1941. X        acl = acl;
  1942. X    else
  1943. X        tmpacl = acl;
  1944. X    return(0);
  1945. X}
  1946. X
  1947. X// Function:    change_flags
  1948. X// Purpose:        change the user's timelimit (possibly permanently)
  1949. X// Input:        flags - the flags to change to
  1950. X//                perm - permanent or not 
  1951. X//            or - or into user flags or and into user flags
  1952. X// Output:        none
  1953. X// Author:        Greg Shaw
  1954. X// Created:        6/9/93
  1955. X
  1956. Xint User::change_flags(unsigned long fl, char perm, char or)
  1957. X{
  1958. X    if (perm)
  1959. X        if (or)
  1960. X            flags |= fl;
  1961. X        else
  1962. X            flags &= fl;
  1963. X    else
  1964. X        if (or)
  1965. X            tmpflags |= fl;
  1966. X        else
  1967. X            tmpflags &= fl;
  1968. X    return(0);
  1969. X}
  1970. X
  1971. X// Function:    change_tl
  1972. X// Purpose:        change the user's timelimit (possibly permanently)
  1973. X// Input:        tl - the timlit to change to
  1974. X//                perm - permanent or not 
  1975. X// Output:        none
  1976. X// Author:        Greg Shaw
  1977. X// Created:        6/8/93
  1978. X
  1979. Xint User::change_tl(int tl, char perm)
  1980. X{
  1981. X    if (perm)
  1982. X        timelimit = tl;
  1983. X    else
  1984. X        tmptl = tl;
  1985. X    return(0);
  1986. X}
  1987. X
  1988. X// Function:    check_card
  1989. X// Purpose:        check the user's access information vs. the card color he has
  1990. X// Input:        none
  1991. X// Output:        (user may be changed)
  1992. X// Author:        Greg Shaw
  1993. X
  1994. Xint User::check_card(void)
  1995. X{
  1996. X    if (card = cardinfo(card_color), card == NULL)
  1997. X        return(-1);
  1998. X    if (acl < card->acl)    // only update info if card better
  1999. X        acl = card->acl;
  2000. X    if (timelimit < card->tl)
  2001. X        timelimit = card->tl;
  2002. X    flags |= card->flags;
  2003. X    return(0);
  2004. X};
  2005. X
  2006. X// Function:    delete_user
  2007. X// Purpose:    delete a user from the BBS
  2008. X// Input:    name - the login name of the user to delete
  2009. X// Output:    none
  2010. X// Author:    Greg Shaw
  2011. X// Created:    4/11/94
  2012. X
  2013. Xint User::delete_user(char *name)
  2014. X{
  2015. X};
  2016. X
  2017. X// Function:    display_info
  2018. X// Purpose:    display the user's information 
  2019. X// Input:    logon - has the user just logged on?  (it gives 'welcome' message
  2020. X// Output:    user information is formatted and printed.
  2021. X// Author:    Greg Shaw
  2022. X// Created:    7/2793
  2023. X
  2024. Xint User::display_info(int logon)
  2025. X{
  2026. X    char     tmpstr[255];    // string
  2027. X    char    *str2;    // used for time
  2028. X
  2029. X    clear();
  2030. X    if (logon)
  2031. X        sprintf(tmpstr,"Welcome back %s %s from %s, %s!",fname,lname,city,state);
  2032. X    else
  2033. X        sprintf(tmpstr,"You are %s %s from %s, %s,",fname,lname,city,state);
  2034. X    sstrcr(tmpstr);
  2035. X    str2 = ctime(&login_time);
  2036. X    str2[strlen(str2)-1] = 0;    // chop \n
  2037. X    sprintf(tmpstr,"You have been on since %s",str2);
  2038. X    sstrcr(tmpstr);
  2039. X    str2 = ctime(&last_login);
  2040. X    str2[strlen(str2)-1] = 0;    // chop \n
  2041. X    sprintf(tmpstr,"You have logged in %d times.  Your last logon was %s",logins,str2);
  2042. X    sstrcr(tmpstr);
  2043. X    sprintf(tmpstr,"Your alias is %s, your editor %s and your terminal is %s",alias,editor,uterm);
  2044. X    sstrcr(tmpstr);
  2045. X    sprintf(tmpstr,"which has %d lines and %d columns.",lines,cols);
  2046. X    sstrcr(tmpstr);
  2047. X    sprintf(tmpstr,"Your membership card color is %s, which entitles you to ",card->colr);
  2048. X    sstrcr(tmpstr);
  2049. X    if (card->kbytes > 0)
  2050. X        sprintf(tmpstr,"to %d minutes on-line and %d k-bytes of downloads every %d hours",timelimit,card->kbytes,waittime());
  2051. X    else
  2052. X        sprintf(tmpstr,"to %d minutes on-line and unlimited downloads every %d hours",timelimit,card->kbytes,waittime());
  2053. X    sstrcr(tmpstr);
  2054. X    sprintf(tmpstr,"You have %d credited minutes, have downloaded %d files",credited,downloads);
  2055. X    sstrcr(tmpstr);
  2056. X    sprintf(tmpstr,"and uploaded %d files.",uploads);
  2057. X    sstrcr(tmpstr);
  2058. X    sprintf(tmpstr,"Last call you used %d minutes and downloaded %d kbytes.",timeused,kused);
  2059. X    sstrcr(tmpstr);
  2060. X    waitcr();
  2061. X    return(0);
  2062. X};
  2063. X
  2064. X// Function:    export
  2065. X// Purpose:    export the user's environment variables
  2066. X// Input:    none
  2067. X// Output:    (environment vars are exported)
  2068. X// Author:    Greg Shaw
  2069. X// Created:    7/2793
  2070. X
  2071. Xint User::export(void)
  2072. X{
  2073. X    char tmpmsg[100];
  2074. X    char *outmsg;
  2075. X
  2076. X    sprintf(tmpmsg,"EDITOR=%s",editor);
  2077. X    if (outmsg = (char *) malloc(strlen(tmpmsg)+1), outmsg == NULL)
  2078. X    {
  2079. X        ap_log("Unable to malloc more environment space.");
  2080. X    }
  2081. X    strcpy(outmsg,tmpmsg);
  2082. X    if (putenv(outmsg) != 0)
  2083. X        ap_log("Unable to export variable.");
  2084. X    sprintf(tmpmsg,"VISUAL=%s",editor);
  2085. X    if (outmsg = (char *) malloc(strlen(tmpmsg)+1), outmsg == NULL)
  2086. X    {
  2087. X        ap_log("Unable to malloc more environment space.");
  2088. X    }
  2089. X    strcpy(outmsg,tmpmsg);
  2090. X    if (putenv(outmsg) != 0)
  2091. X        ap_log("Unable to export variable.");
  2092. X    sprintf(tmpmsg,"TERM=%s",uterm);
  2093. X    if (outmsg = (char *) malloc(strlen(tmpmsg)+1), outmsg == NULL)
  2094. X    {
  2095. X        ap_log("Unable to malloc more environment space.");
  2096. X    }
  2097. X    strcpy(outmsg,tmpmsg);
  2098. X    if (putenv(outmsg) != 0)
  2099. X        ap_log("Unable to export variable.");
  2100. X    sprintf(tmpmsg,"LINES=%s",lines);
  2101. X    if (outmsg = (char *) malloc(strlen(tmpmsg)+1), outmsg == NULL)
  2102. X    {
  2103. X        ap_log("Unable to malloc more environment space.");
  2104. X    }
  2105. X    strcpy(outmsg,tmpmsg);
  2106. X    if (putenv(outmsg) != 0)
  2107. X        ap_log("Unable to export variable.");
  2108. X    sprintf(tmpmsg,"COLUMNS=%s",cols);
  2109. X    if (outmsg = (char *) malloc(strlen(tmpmsg)+1), outmsg == NULL)
  2110. X    {
  2111. X        ap_log("Unable to malloc more environment space.");
  2112. X    }
  2113. X    strcpy(outmsg,tmpmsg);
  2114. X    if (putenv(outmsg) != 0)
  2115. X        ap_log("Unable to export variable.");
  2116. X    return(0);
  2117. X};
  2118. X
  2119. X
  2120. X// Function:    get
  2121. X// Purpose:        get the user's info from the user list
  2122. X// Input:        none
  2123. X// Output:        object is loaded or an error is returned
  2124. X// Author:        Greg Shaw
  2125. X// Created:        7/13/93
  2126. X// Notes:        the user file is a plain text file (to allow editing).  
  2127. X//                its format is such:
  2128. X//                    [A login_name firstname lastname]
  2129. X//                    [B terminal_type last_logon #_logins downloads uploads card color]
  2130. X//                    [C private_msgs public_msgs credited_time has_color editor lines cols]
  2131. X//                    [D flags access_level timelimit timeused_last_call]
  2132. X//                the above format includes the brackets and lines (for reference)
  2133. X
  2134. Xint User::get(char *name)
  2135. X{
  2136. X    FILE    *ufile;
  2137. X    char    *u;
  2138. X    char    finame[255];        // filename
  2139. X    char    line[255];        // one line in file (255 max)
  2140. X    char    logname[10];    // user login name
  2141. X    char    found;            // user found?
  2142. X    char    linenum;        // used to look for appropriate line
  2143. X    char    c;                // input char
  2144. X    unsigned char    of;        // offset into line
  2145. X    int    x;
  2146. X    struct passwd *userent;    // user entry in password file
  2147. X
  2148. X    if (name == NULL)
  2149. X        strcpy(logname,username());        // get user's login information    
  2150. X    else    
  2151. X        strcpy(logname,name);
  2152. X    if (strcpy(finame,getenv("BBSDIR")), fname == NULL)
  2153. X    {
  2154. X        sprintf(finame,"user.get: BBSDIR environment variable not set for %s",logname);
  2155. X        ap_log(finame);
  2156. X        return(-1);
  2157. X    }
  2158. X    strcat(finame,"/admin/userlog");
  2159. X    linenum = 0;        // look for first line first
  2160. X    if (ufile = bopen(finame,"r"), ufile != NULL)
  2161. X    {
  2162. X        found = 0;
  2163. X        while (!found && !feof(ufile))
  2164. X        {
  2165. X            of = 0;
  2166. X            while (c = fgetc(ufile), c != '\r' && c != '\n' && !feof(ufile))
  2167. X                if (c != ']')    // skip trailing left bracket
  2168. X                line[of++] = c;
  2169. X            line[of] = 0;    // add null
  2170. X            switch(linenum)
  2171. X            {
  2172. X            case 0:    // first line
  2173. X                if (line[0] == '[' && line[1] == 'A')    // got line 1?
  2174. X                {
  2175. X                    x = sscanf(&line[2],"%s %s %s %s %s %s",login_name,
  2176. X                        fname, lname, alias, state, city);
  2177. X                    if (u = strchr(city,']'), u != NULL)
  2178. X                    {    // convert any left brackets to null
  2179. X                        u++;
  2180. X                        u[0] = 0;
  2181. X                    }
  2182. X                    if (strcmp(login_name,logname) == 0)
  2183. X                    {
  2184. X                        linenum++;        // get next line
  2185. X                    }
  2186. X                }
  2187. X                break;
  2188. X            case 1:    // second line
  2189. X                if (line[0] == '[' && line[1] == 'B')    // got line 2?
  2190. X                {
  2191. X                    if (sscanf(&line[2],"%s %ld %d %d %d %s",uterm,
  2192. X                        &last_login, &logins, &downloads, &uploads,
  2193. X                        card->colr) != 6)
  2194. X                    {
  2195. X                        ap_log("user.get: bad read from user file.  Corrupted?");
  2196. X                        sprintf(finame,"user.get: bad user record was %s, line B",login_name);
  2197. X                        ap_log(finame);
  2198. X                        return(-1);
  2199. X                    }
  2200. X                    linenum++;        // get next line
  2201. X                    if (!strcmp(card->colr,"red"))
  2202. X                        card_color = 0;
  2203. X                    if (!strcmp(card->colr,"blue"))
  2204. X                        card_color = 1;
  2205. X                    if (!strcmp(card->colr,"green"))
  2206. X                        card_color = 2;
  2207. X                    if (!strcmp(card->colr,"white"))
  2208. X                        card_color = 3;
  2209. X                    if (!strcmp(card->colr,"grey"))
  2210. X                        card_color = 4;
  2211. X                    if (!strcmp(card->colr,"pink"))
  2212. X                        card_color = 5;
  2213. X                    if (!strcmp(card->colr,"yellow"))
  2214. X                        card_color = 6;
  2215. X                    if (!strcmp(card->colr,"black"))
  2216. X                        card_color = 7;
  2217. X                }
  2218. X                break;
  2219. X            case 2:    // third line
  2220. X                if (line[0] == '[' && line[1] == 'C')    // got line 3?
  2221. X                {
  2222. X                    if (sscanf(&line[2],"%d %d %d %d %s %d %d",&priv_msgs,&pub_msgs,
  2223. X                        &credited, &has_color, editor, &lines, &cols) != 7)
  2224. X                    {
  2225. X                        ap_log("user.get: bad read from user file.  Corrupted?");
  2226. X                        sprintf(finame,"user.get: bad user record was %s, line C",login_name);
  2227. X                        ap_log(finame);
  2228. X                        return(-1);
  2229. X                    }
  2230. X                    linenum++;        // get next line
  2231. X                }
  2232. X                break;
  2233. X            case 3:    // fourth line
  2234. X                if (line[0] == '[' && line[1] == 'D')    // got line 4?
  2235. X                {
  2236. X                    if (sscanf(&line[2],"%lx %d %d %d %ld %d",&flags,
  2237. X                        &acl, &timelimit, &timeused, &anniversary,&kused) != 6)
  2238. X                    {
  2239. X                        ap_log("user.get: bad read from user file.  Corrupted?");
  2240. X                        sprintf(finame,"user.get: bad user record was %s, line D",login_name);
  2241. X                        ap_log(finame);
  2242. X                        return(-1);
  2243. X                    }
  2244. X                    linenum++;        // get next line
  2245. X                }
  2246. X                break;
  2247. X            }    
  2248. X            if (linenum == 4)    // got him.
  2249. X            {
  2250. X                found++;
  2251. X                bclose(ufile);
  2252. X                logins++;
  2253. X                if (name != NULL && (login_time - last_login)/60 < waittime())
  2254. X                {
  2255. X                    if ((timelimit - timeused) < 5)
  2256. X                    {
  2257. X                        clear();
  2258. X                        sstrcr("You do not have enough unused time on the BBS to logon.");
  2259. X                        sprintf(finame,"In the future, please wait at least %d hours before logging on again.",waittime());
  2260. X                        sstrcr(finame);
  2261. X                        cr();
  2262. X                        cr();
  2263. X                        waitcr();
  2264. X                        sstrcr("Thanks for Calling!");
  2265. X                        exit(0);
  2266. X                    }
  2267. X                }
  2268. X                else
  2269. X                {
  2270. X                    kused = 0;    // start all counters over
  2271. X                    timeused = 0;
  2272. X                    credited = 0;
  2273. X                }
  2274. X                tmpflags = flags;
  2275. X                tmpacl = acl;
  2276. X                tmptl = timelimit;
  2277. X                if (name == NULL)
  2278. X                {
  2279. X                    sprintf(line,"Logon for %s %s",fname,lname);
  2280. X                    ap_log(line);
  2281. X                    export();    // export his environment variables
  2282. X                    check_card();    // check his access level vs. card
  2283. X                }
  2284. X                return(1);    // return 1 for new user only
  2285. X            }
  2286. X        }
  2287. X    }
  2288. X    bclose(ufile);    // close just in case
  2289. X    // didn't find him in user file.  Need to get his information
  2290. X    if (name != NULL) // error - unable to find user in userlog
  2291. X    {
  2292. X        sprintf(line,"Unable to find %s in userlog.",name);
  2293. X        ap_log(line);
  2294. X        return(0);
  2295. X    }    
  2296. X    strcpy(login_name,logname);        // get login name    
  2297. X    sstrcr("I am unable to find you in the user list of the bbs.");    
  2298. X    sstr("Would you like to register for the bbs? ");
  2299. X    if (!yesno())
  2300. X    {
  2301. X        fflush(stdout);
  2302. X        sprintf(finame,"user.get: %s decided not to register for bbs.",logname);
  2303. X        ap_log(finame);
  2304. X        return(-1);
  2305. X    }
  2306. X    cr();
  2307. X    if (userent = getpwnam((char *)username()), userent == NULL)
  2308. X    {
  2309. X        sprintf(finame,"user.get: Unable to get user %s's password entry!",logname);
  2310. X        ap_log(finame);
  2311. X        return(-1);
  2312. X    }
  2313. X    sscanf(userent->pw_gecos,"%s %s",fname,lname);    // get user name
  2314. X    getinfo(1);    // get user information
  2315. X    export();    // export his environment variables
  2316. X    check_card();    // check his access level vs. card
  2317. X    append();
  2318. X    sprintf(line,"Logon for %s %s",fname,lname);
  2319. X    ap_log(line);
  2320. X    return(0);
  2321. X}
  2322. X
  2323. X// Function:    getinfo
  2324. X// Purpose:        prompt the user for information to setup the user object
  2325. X// Input:        firsttime - is this the first logon by user?
  2326. X// Output:        (user questions)
  2327. X// Author:        Greg Shaw
  2328. X// Created:        7/25/93
  2329. X
  2330. Xint User::getinfo(char firsttime)
  2331. X{
  2332. X    char    loop;            // loop counter
  2333. X    char    done;            // loop counter
  2334. X    char    entered;        // entered anything?
  2335. X    char    tmpstr[255];
  2336. X    char    anotherstr[50];        // another string
  2337. X    char    finame[255];        // filename
  2338. X    char    logname[10];    // user login name
  2339. X
  2340. X    loop = 1;
  2341. X    entered = 0;
  2342. X    while (loop)
  2343. X    {
  2344. X        clear();        // clear screen
  2345. X        if (!firsttime || entered)
  2346. X        {
  2347. X            cr();
  2348. X            cr();
  2349. X            cr();
  2350. X            sstrcr("You have entered the following:");
  2351. X            cr();
  2352. X            sprintf(finame,"Login: %s",login_name);
  2353. X            sstrcr(finame);
  2354. X            sprintf(finame,"Real Name: %s %s",fname,lname);
  2355. X            sstrcr(finame);
  2356. X            sprintf(finame,"Alias: %s",alias);
  2357. X            sstrcr(finame);
  2358. X            sprintf(finame,"Calling from: %s, %s",city,state);
  2359. X            sstrcr(finame);
  2360. X            sprintf(finame,"Terminal type: %s",uterm);
  2361. X            sstrcr(finame);
  2362. X            sprintf(finame,"Terminal supports color: %s",has_color?"Yes":"No");
  2363. X            sstrcr(finame);
  2364. X            sprintf(finame,"Editor: %s",editor);
  2365. X            sstrcr(finame);
  2366. X            sprintf(finame,"Lines: %d  Columns: %d",lines,cols);
  2367. X            sstrcr(finame);
  2368. X            cr();
  2369. X            sstr("Is this correct? ");
  2370. X            if (yesno())
  2371. X                loop = 0;
  2372. X        }
  2373. X        if (loop)    // still looping?
  2374. X        {
  2375. X            if (!firsttime)
  2376. X                sstrcr("Enter 'x' to keep your old entry in any field.");
  2377. X            strcpy(logname,username());        // get user's login information    
  2378. X            done = 0;
  2379. X            while (!done)
  2380. X            {
  2381. X                sstrcr("If your city is two words, please enter the city as a word separated by a dash.");
  2382. X                sstrcr("Example: Fort Collins would be Fort-Collins.");
  2383. X                sstr("To begin, please enter the city you are calling from: ");
  2384. X                if (gstr(tmpstr,20), strcmp(tmpstr,"") == 0)
  2385. X                    continue;
  2386. X                if (!strcmp(tmpstr,"x"))
  2387. X                {
  2388. X                    if (firsttime)        // no empty entries for first time
  2389. X                        continue;
  2390. X                }
  2391. X                else
  2392. X                    strcpy(city,tmpstr);
  2393. X                done++;
  2394. X            }
  2395. X            cr();
  2396. X            done = 0;
  2397. X            while (!done)
  2398. X            {
  2399. X                sstrcr("Please enter the state where you are calling from.");
  2400. X                sstr("Only two letters, please.  (example: CO for Colorado) ");
  2401. X                if (gstr(tmpstr,2), strcmp(tmpstr,"") == 0)
  2402. X                    continue;
  2403. X                if (!strcmp(tmpstr, "x"))
  2404. X                {
  2405. X                    if (firsttime)        // no empty entries for first time
  2406. X                        continue;
  2407. X                }
  2408. X                else
  2409. X                    strcpy(state,tmpstr);
  2410. X                done++;
  2411. X            }
  2412. X            cr();
  2413. X            done = 0;
  2414. X            while (!done)
  2415. X            {
  2416. X                sstrcr("Now comes a tough question.  On Unix (which is what this");
  2417. X                sstrcr("BBS runs under), it is *VERY* important that you get ");
  2418. X                sstrcr("your terminal type (the type of terminal emulation supported");
  2419. X                sstrcr("by your software) entered correctly.");
  2420. X                cr();
  2421. X                sstrcr("If entered incorrectly, it can cause problems in");
  2422. X                sstrcr("programs external to the BBS, such as mail programs.");
  2423. X                sstrcr("Also, if your terminal type is entered");
  2424. X                sstrcr("correctly, it will enable the bbs to use some of the more");
  2425. X                sstrcr("advanced features of your program.");
  2426. X                cr();
  2427. X                sstrcr("If you're calling in from a PC-ANSI emulating terminal, I'd");
  2428. X                sstrcr("recommend the 'ansi' terminal type.");
  2429. X                sstrcr("'vt100' is another popular terminal type.");
  2430. X                sstrcr("Unless you *KNOW* what terminal type you've got (like a wyse60 terminal),");
  2431. X                sstrcr("enter 'vt100' or 'ansi'");
  2432. X                cr();
  2433. X                sstrcr("Note: You must enter the terminal type in lower case.");
  2434. X                sstr("What terminal type would you like to use? ");
  2435. X                if (gstr(tmpstr,20), strcmp(tmpstr,"") == 0)
  2436. X                    continue;
  2437. X                if (!strcmp(tmpstr,"x"))
  2438. X                {
  2439. X                    if (firsttime)        // no empty entries for first time
  2440. X                        continue;
  2441. X                }
  2442. X                else
  2443. X                    strcpy(uterm,tmpstr);
  2444. X                done++;
  2445. X            }
  2446. X            cr();
  2447. X            cr();
  2448. X            sstr("Does your terminal program support color? ");
  2449. X            if (yesno())
  2450. X                has_color = 1;
  2451. X            else
  2452. X                has_color = 0;
  2453. X            cr();
  2454. X            cr();
  2455. X            if (strcpy(finame,getenv("BBSDIR")), finame == NULL)
  2456. X            {
  2457. X                sprintf(finame,"user.get: BBSDIR env var not set for %s",logname);
  2458. X                ap_log(finame);
  2459. X                return(-1);
  2460. X            }
  2461. X            strcat(finame,"/text/editors");
  2462. X            sprintf(tmpstr,"Viewing %s",finame);
  2463. X            sysopstrcr(tmpstr);
  2464. X            display_file(finame,1);        // display file with paging
  2465. X            cr();
  2466. X            cr();
  2467. X            done = 0;
  2468. X            while (!done)
  2469. X            {
  2470. X                sstrcr("Note: the editor name must be lower case");
  2471. X                sstr("Which editor would you like to use? ");
  2472. X                if (gstr(tmpstr,14), strcmp(tmpstr,"") == 0)
  2473. X                    continue;
  2474. X                if (!strcmp(tmpstr,"x"))
  2475. X                {
  2476. X                    if (firsttime)        // no empty entries for first time
  2477. X                        continue;
  2478. X                }
  2479. X                else
  2480. X                    strcpy(editor,tmpstr);
  2481. X                done++;
  2482. X            }
  2483. X            cr();
  2484. X            cr();
  2485. X            sstrcr("You may also enter an alias, or, you may use your logon");
  2486. X            sstrcr("name as your alias.  Would you like to user your logon as");
  2487. X            sstr("your alias? (y/n) ");
  2488. X            if (yesno())
  2489. X                strcpy(alias,logname);
  2490. X            else 
  2491. X            {
  2492. X                done = 0;
  2493. X                while (!done)
  2494. X                {
  2495. X                    sstrcr("Your alias must be only one word.");
  2496. X                    sstr("Please enter your alias: ");
  2497. X                    if (gstr(tmpstr,20), strcmp(tmpstr,"") == 0)
  2498. X                        continue;
  2499. X                    if (!strcmp(tmpstr,"x"))
  2500. X                    {
  2501. X                        if (firsttime)        // no empty entries for first time
  2502. X                            continue;
  2503. X                    }
  2504. X                    else
  2505. X                        if (sscanf(tmpstr,"%s%s",alias,anotherstr) != 1)
  2506. X                            continue;
  2507. X                    done++;
  2508. X                }
  2509. X            }
  2510. X            cr();
  2511. X            cr();
  2512. X            done = 0;
  2513. X            while (!done)
  2514. X            {
  2515. X                sstrcr("I need to know how many lines are on your screen.");
  2516. X                sstrcr("Enter 'x' for the default 24 lines per screen.");
  2517. X                sstr("How many lines does your terminal support? ");
  2518. X                if (gstr(tmpstr,5), strcmp(tmpstr,"") == 0)
  2519. X                    continue;
  2520. X                if (tmpstr[0] == 'x')
  2521. X                {
  2522. X                    lines = 24;
  2523. X                }
  2524. X                else
  2525. X                    sscanf(tmpstr,"%d",&lines);
  2526. X                done++;
  2527. X            }
  2528. X            cr();
  2529. X            cr();
  2530. X            done = 0;
  2531. X            while (!done)
  2532. X            {
  2533. X                sstrcr("I need to know how many columns are on your screen.");
  2534. X                sstrcr("Enter 'x' for the default 80 columns per screen.");
  2535. X                sstr("How many columns does your terminal support? ");
  2536. X                if (gstr(tmpstr,5), strcmp(tmpstr,"") == 0)
  2537. X                    continue;
  2538. X                if (tmpstr[0] == 'x')
  2539. X                {
  2540. X                    cols = 80;
  2541. X                }
  2542. X                else
  2543. X                    sscanf(tmpstr,"%d",&cols);
  2544. X                done++;
  2545. X            }
  2546. X            entered++;
  2547. X        }
  2548. X    }
  2549. X    export();
  2550. X    return(0);
  2551. X};
  2552. X
  2553. X// Function:    inactive_list
  2554. X// Purpose:    list the inactive (people who haven't called lately) users
  2555. X// Input:    none
  2556. X// Output:    A list of users who haven't called in a specified time
  2557. X// Author:    Greg Shaw
  2558. X// Created:    4/3/94
  2559. X
  2560. Xint User::inactive_list(void)
  2561. X{
  2562. X    char    tmpstr[255];
  2563. X    char    line[150];
  2564. X    char    c;
  2565. X    char    key[MAX_FILENAMELENGTH+1];
  2566. X    char    uname[10];
  2567. X    char    fullname[50];
  2568. X    char    fname[15];
  2569. X    char    lname[15];
  2570. X    char    tmp[2][15];
  2571. X    char    state[50];
  2572. X    char    city[50];
  2573. X    char    llogon[10];
  2574. X    char    from[50];
  2575. X    char    *sptr;
  2576. X    int    logins;
  2577. X    int    uls,dls;
  2578. X    time_t    laston;
  2579. X    time_t    today;
  2580. X    struct tm *tmdata;
  2581. X    int    off;
  2582. X    int    found;
  2583. X    int    days;
  2584. X    FILE    *infile;
  2585. X    
  2586. X    
  2587. X    clear();
  2588. X    time(&today);
  2589. X    // get number of days inactive to search for
  2590. X    sstrcr("I need to know how many days to search back to list");
  2591. X    sstrcr("the inactive users.  For example, 30 would mean that");
  2592. X    sstrcr("the user hasn't called in the last 30 days minimum.");
  2593. X    cr();
  2594. X    sstr("How many days ago since last call should I list? ");
  2595. X    gstr(key,MAX_FILENAMELENGTH);
  2596. X    if (key[0] == 0 || sscanf(key,"%d",&days) != 1)
  2597. X        return(0);
  2598. X    sprintf(tmpstr,"%s/admin/userlog",getenv("BBSDIR"));        
  2599. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  2600. X    {
  2601. X        ap_log("Unable to open userlog for read.");
  2602. X        return(0);
  2603. X    }
  2604. X    found = 0;
  2605. X    sstrcr("Username        From            Last Logon   Uls  Dls");
  2606. X    while (!feof(infile))
  2607. X    {
  2608. X        off = 0;
  2609. X        while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  2610. X            line[off++] = c;
  2611. X        line[off] = 0;
  2612. X        if (line[0] == '[')
  2613. X        {
  2614. X            if (line[1] == 'A')
  2615. X            {
  2616. X                sscanf(&line[2],"%s %s %s %s %s %s %s %s", uname, fname, lname, alias, state, city,tmp[0], tmp[1]);
  2617. X                strcat(city,tmp[0]);
  2618. X                strcat(city,tmp[1]);
  2619. X                if (sptr = strchr(city,']'), sptr != NULL)
  2620. X                    sptr[0] = 0;
  2621. X            } else if (line[1] == 'B')
  2622. X            {
  2623. X                sscanf(&line[2],"%*s %ld %d %d %d %*s",&laston, &logins,&uls,&dls);
  2624. X                sprintf(fullname,"%s %s",fname,lname);
  2625. X                sprintf(from,"%s, %s",city,state);
  2626. X                tmdata = localtime(&laston);
  2627. X                strftime(llogon, 12, "%b %d,%Y", tmdata);
  2628. X                if ((today - laston)/86400 >= days)
  2629. X                {
  2630. X                    sprintf(tmpstr,"%-15s %-15s %s   %d    %d",fullname,from,llogon,uls,dls);
  2631. X                    sstrcr(tmpstr);
  2632. X                    found++;
  2633. X                }
  2634. X                if (found == 17)
  2635. X                {
  2636. X                    found = 0;
  2637. X                    waitcr();
  2638. X                    sstr("Continue listing? ");
  2639. X                    if (!yesno())
  2640. X                    {
  2641. X                        bclose(infile);
  2642. X                        return(0);
  2643. X                    }
  2644. X                }
  2645. X            }
  2646. X        }
  2647. X    }
  2648. X    cr();
  2649. X    sstrcr("No more found.");
  2650. X    bclose(infile);
  2651. X    waitcr();
  2652. X    return(0);
  2653. X};
  2654. X
  2655. X// Function:    inactive_delete
  2656. X// Purpose:    delete inactive users on the BBS
  2657. X// Input:    none
  2658. X// Output:    A list of users who haven't called in a specified time
  2659. X// Author:    Greg Shaw
  2660. X// Created:    4/21/94
  2661. X
  2662. Xint User::inactive_delete(void)
  2663. X{
  2664. X    char    tmpstr[255];
  2665. X    char    line[150];
  2666. X    char    c,b;
  2667. X    char    key[MAX_FILENAMELENGTH+1];
  2668. X    char    uname[10];
  2669. X    char    fullname[50];
  2670. X    char    fname[15];
  2671. X    char    lname[15];
  2672. X    char    tmp[2][15];
  2673. X    char    state[50];
  2674. X    char    city[50];
  2675. X    char    llogon[10];
  2676. X    char    from[50];
  2677. X    char    *sptr;
  2678. X    int    x;
  2679. X    int    logins;
  2680. X    int    uls,dls;
  2681. X    time_t    laston;
  2682. X    time_t    today;
  2683. X    struct tm *tmdata;
  2684. X    int    off;
  2685. X    int    found;
  2686. X    int    days;
  2687. X    FILE    *infile;
  2688. X    FILE    *outfile;
  2689. X    
  2690. X    
  2691. X    clear();
  2692. X    time(&today);
  2693. X    // get number of days inactive to search for
  2694. X    sstrcr("I need to know how many days to search back to delete");
  2695. X    sstrcr("the inactive users.  For example, 30 would mean that");
  2696. X    sstrcr("the user hasn't called in at least 30 days.");
  2697. X    cr();
  2698. X    sstr("How many days ago since last call should I delete users? ");
  2699. X    gstr(key,MAX_FILENAMELENGTH);
  2700. X    if (key[0] == 0 || sscanf(key,"%d",&days) != 1)
  2701. X        return(0);
  2702. X    sprintf(tmpstr,"Will delete users %d days.",days);
  2703. X    sstrcr(tmpstr);
  2704. X    cr();
  2705. X    sstrcr("Would you like me to delete Automatically (no prompting)");
  2706. X    sstr("or Interactively (prompted) ? (A/I) ");
  2707. X    while (b = tolower(gch(1)), b != 'a' && b != 'i');
  2708. X    cr();
  2709. X    if (b == 'i')    // interactively
  2710. X    {
  2711. X        sstrcr("Prompting enabled...");
  2712. X        waitcr();
  2713. X    }
  2714. X    sprintf(tmpstr,"%s/admin/userlog",getenv("BBSDIR"));        
  2715. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  2716. X    {
  2717. X        ap_log("Unable to open userlog for read.");
  2718. X        sstrcr("Unable to open userlog for read.");
  2719. X        waitcr();
  2720. X        return(0);
  2721. X    }
  2722. X    strcat(tmpstr,".new"); // get 'new' filename
  2723. X    if (outfile = bopen(tmpstr,"w"), outfile == NULL)
  2724. X    {
  2725. X        ap_log("Unable to open userlog.new for write.");
  2726. X        sstrcr("Unable to open userlog.new for write.");
  2727. X        waitcr();
  2728. X        return(0);
  2729. X    }
  2730. X    found = 0;
  2731. X    while (!feof(infile))
  2732. X    {
  2733. X        off = 0;
  2734. X        while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  2735. X            line[off++] = c;
  2736. X        line[off] = 0;
  2737. X        if (line[0] == '[')
  2738. X        {
  2739. X            if (line[1] == 'A')
  2740. X            {
  2741. X                sscanf(&line[2],"%s %s %s %s %s %s %s %s", uname, fname, lname, alias, state, city,tmp[0], tmp[1]);
  2742. X                strcat(city,tmp[0]);
  2743. X                strcat(city,tmp[1]);
  2744. X                if (sptr = strchr(city,']'), sptr != NULL)
  2745. X                    sptr[0] = 0;
  2746. X            } else if (line[1] == 'B')
  2747. X            {
  2748. X                if (sscanf(&line[2],"%s %ld %d %d %d %s",uterm, &laston, &logins,&uls,&dls,card->colr) != 6)
  2749. X                {
  2750. X                    sprintf(tmpstr,"Error found in line B userlog in entry %s %s",fname,lname);
  2751. X                    ap_log(tmpstr);
  2752. X                    sstrcr("Error found in userlog.  Clean aborted.");
  2753. X                    waitcr();
  2754. X                    return(0);
  2755. X                }
  2756. X                sprintf(fullname,"%s %s",fname,lname);
  2757. X                sprintf(from,"%s, %s",city,state);
  2758. X                tmdata = localtime(&laston);
  2759. X                strftime(llogon, 12, "%b %d,%Y", tmdata);
  2760. X                if ((today - laston)/86400 >= days)
  2761. X                {
  2762. X                    sprintf(tmpstr,"%-15s %-15s %s   %d    %d",fullname,from,llogon,uls,dls);
  2763. X                    sstrcr(tmpstr);
  2764. X                    if (b == 'i')    // interactive?
  2765. X                    {
  2766. X                        sstr("Delete this user?  ");
  2767. X                        if (yesno())
  2768. X                            continue;
  2769. X                    }
  2770. X                    else 
  2771. X                        continue;
  2772. X                }
  2773. X                for (x=0; x<2; x++)
  2774. X                    if (strlen(tmp[x]) < 2)
  2775. X                        tmp[x][0] = 0;
  2776. X                // save info and next two lines
  2777. X                fprintf(outfile,"[A %s %s %s %s %s %s %s %s ]\n", uname, fname, lname, alias, state, city, tmp[0], tmp[1]);
  2778. X                fprintf(outfile,"%s\n",line);
  2779. X                x = 0;
  2780. X                while (x < 2)
  2781. X                {
  2782. X                    if (c = fgetc(infile), c == '\n' || c == '\r')
  2783. X                        x++;
  2784. X                    fputc(c,outfile);
  2785. X                }
  2786. X            }
  2787. X        }
  2788. X    }
  2789. X    cr();
  2790. X    bclose(outfile);
  2791. X    sprintf(tmpstr,"%s/admin/userlog",getenv("BBSDIR"));        
  2792. X    sprintf(line,"%s/admin/userlog.old",getenv("BBSDIR"));
  2793. X    rename(tmpstr,line);
  2794. X    sprintf(tmpstr,"%s/admin/userlog.new",getenv("BBSDIR"));        
  2795. X    sprintf(line,"%s/admin/userlog",getenv("BBSDIR"));
  2796. X    rename(tmpstr,line);
  2797. X    waitcr();
  2798. X    return(0);
  2799. X};
  2800. X
  2801. X// Function:    list
  2802. X// Purpose:    return a user record 
  2803. X// Input:    path - the path to the user file 
  2804. X// Output:    a list of users on the bbs - 
  2805. X// Author:    Greg Shaw
  2806. X// Created:    6/8/93
  2807. X
  2808. Xint User::list(int search, int sysop)
  2809. X{
  2810. X    char    tmpstr[255];
  2811. X    char    line[150];
  2812. X    char    c;
  2813. X    char    key[MAX_FILENAMELENGTH+1];
  2814. X    char    uname[10];
  2815. X    char    alias[25];
  2816. X    char    fname[15];
  2817. X    char    lname[15];
  2818. X    char    tmp[2][15];
  2819. X    char    state[50];
  2820. X    char    city[50];
  2821. X    char    *sptr;
  2822. X    int    logins;
  2823. X    time_t    laston;
  2824. X    int    off;
  2825. X    int    found;
  2826. X    FILE    *infile;
  2827. X    
  2828. X    
  2829. X    clear();
  2830. X    sprintf(tmpstr,"%s/admin/userlog",getenv("BBSDIR"));        
  2831. X    if (infile = bopen(tmpstr,"r"), infile == NULL)
  2832. X    {
  2833. X        ap_log("Unable to open userlog for read.");
  2834. X        return(0);
  2835. X    }
  2836. X    if (search)
  2837. X    {
  2838. X        sstrcr("You may enter any number of characters to search for.");
  2839. X        cr();        
  2840. X        sstr("Search for what characters? ");
  2841. X        gstr(key,MAX_FILENAMELENGTH);
  2842. X        if (key[0] == 0)
  2843. X            return(0);
  2844. X        // search for characters in userlog
  2845. X        found = 0;
  2846. X        while (!feof(infile))
  2847. X        {
  2848. X            off = 0;
  2849. X            while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  2850. X                line[off++] = c;
  2851. X            line[off] = 0;
  2852. X            if (line[0] == '[')
  2853. X            {
  2854. X                if (line[1] == 'A')
  2855. X                {
  2856. X                    sscanf(&line[2],"%s %s %s %s %s %s %s %s", uname, fname, lname, alias, state, city,tmp[0], tmp[1]);
  2857. X                    strcat(city,tmp[0]);
  2858. X                    strcat(city,tmp[1]);
  2859. X                    if (sptr = strchr(city,']'), sptr != NULL)
  2860. X                        sptr[0] = 0;
  2861. X                    if (strstr(line,key) != NULL)
  2862. X                    {
  2863. X                        sprintf(tmpstr,"Name: %s %s from %s, %s",fname,lname,city,state);
  2864. X                        sstrcr(tmpstr);
  2865. X                        sprintf(tmpstr,"Logon: %s Alias: %s ",uname,alias);
  2866. X                        sstrcr(tmpstr);
  2867. X                        found++;
  2868. X                    }
  2869. X                } else if (found && line[1] == 'B')
  2870. X                {
  2871. X                    sscanf(&line[2],"%*s %ld %d %*d %*d %*s",&laston, &logins);
  2872. X                    sptr = ctime(&laston);
  2873. X                    sptr[strlen(sptr)-1] = 0;    // chop \n
  2874. X                    sprintf(tmpstr,"Number of logons: %d  Last Logon: %s ",logins,sptr);
  2875. X                    sstrcr(tmpstr);
  2876. X                    waitcr();
  2877. X                    if (sysop)
  2878. X                    {
  2879. X                        sstr("Continue, Edit or Delete? ");
  2880. X                        while (c = toupper(gch(1)), c != 'D' && c != 'C' && c != 'E');
  2881. X                        if (c == 'D')
  2882. X                        {
  2883. X                            bclose(infile);
  2884. X                            delete_user(uname);
  2885. X                            return(0);
  2886. X                        }
  2887. X                        else if (c == 'E')
  2888. X                        {
  2889. X                            bclose(infile);
  2890. X                            if (get(uname))
  2891. X                            {
  2892. X                                check_card();
  2893. X                                sysop_edit();
  2894. X                            }
  2895. X                            else
  2896. X                            {
  2897. X                                sprintf(tmpstr,"Unable to get %s for sysop edit.",uname);
  2898. X                                ap_log(tmpstr);
  2899. X                            }
  2900. X                            return(0);
  2901. X                        }
  2902. X                    }
  2903. X                    else 
  2904. X                    {
  2905. X                        sstr("Continue search? ");
  2906. X                        if (!yesno())
  2907. X                        {
  2908. X                            bclose(infile);
  2909. X                            return(0);
  2910. X                        }
  2911. X                    }
  2912. X                    found = 0;
  2913. X                }
  2914. X            }
  2915. X        }
  2916. X        bclose(infile);
  2917. X    }
  2918. X    else
  2919. X    {
  2920. X        found = 0;
  2921. X        while (!feof(infile))
  2922. X        {
  2923. X            off = 0;
  2924. X            while (c = fgetc(infile), c != '\n' && c != '\r' && !feof(infile))
  2925. X                line[off++] = c;
  2926. X            if (line[0] == '[')
  2927. X            {
  2928. X                if (line[1] == 'A')
  2929. X                {
  2930. X                    sscanf(&line[2],"%s %s %s %s %s %s %s %s", uname, fname, lname, alias, state, city,tmp[0], tmp[1]);
  2931. X                    strcat(city,tmp[0]);
  2932. X                    strcat(city,tmp[1]);
  2933. X                    if (sptr = strchr(city,']'), sptr != NULL)
  2934. X                        sptr[0] = 0;
  2935. X                    sprintf(tmpstr,"%s %s from %s, %s",fname,lname,city,state);
  2936. X                    sstrcr(tmpstr);
  2937. X                    sprintf(tmpstr,"Logon: %s Alias: %s ",uname,alias);
  2938. X                    sstrcr(tmpstr);
  2939. X                } else if (line[1] == 'B')
  2940. X                {
  2941. X                    sscanf(&line[2],"%*s %ld %d %*d %*d %*s",&laston, &logins);
  2942. X                    sptr = ctime(&laston);
  2943. X                    sptr[strlen(sptr)-1] = 0;    // chop \n
  2944. X                    sprintf(tmpstr,"Number of logons: %d  Last Logon: %s ",logins,sptr);
  2945. X                    sstrcr(tmpstr);
  2946. X                    cr();
  2947. X                    if (found == 6)
  2948. X                    {
  2949. X                        found = 0;
  2950. X                        waitcr();
  2951. X                        sstr("Continue listing? ");
  2952. X                        if (!yesno())
  2953. X                        {
  2954. X                            bclose(infile);
  2955. X                            return(0);
  2956. X                        }
  2957. X                    }
  2958. X                    found++;
  2959. X                }
  2960. X            }
  2961. X        }
  2962. X        cr();
  2963. X    }
  2964. X    cr();
  2965. X    sstrcr("No more found.");
  2966. X    waitcr();
  2967. X    return(0);
  2968. X}
  2969. X
  2970. X// Function:    mailavail
  2971. X// Purpose:    return true if mail for the user is available
  2972. X// Input:    none
  2973. X// Output:    1 for mail.  0 for no mail
  2974. X// Author:        Greg Shaw
  2975. X// Created:        8/10/93
  2976. X
  2977. Xint User::mailavail(void)
  2978. X{
  2979. X    struct stat fistat;    // file status record
  2980. X    char    tmpstr[255];    // tmpstr
  2981. X    time_t    now = 0L;        // current time
  2982. X    static time_t    then = 0L;    // previous check time
  2983. X
  2984. X    time(&now);
  2985. X    if (abs(now - then) > mailchecktime())    // seconds elapsed?
  2986. X    {
  2987. X        sprintf(tmpstr,"%s/%s",mailspool(),login_name);
  2988. X        if (stat(tmpstr,&fistat) == 0 && S_ISREG(fistat.st_mode))
  2989. X        {
  2990. X            if (mail_check == 0)    // just check size the first time
  2991. X            {
  2992. X                    mail_check = fistat.st_mtime;// save modification time
  2993. X                    if (mail_size = fistat.st_size, mail_size > 0)
  2994. X                        return(1);
  2995. X            }
  2996. X            else // check date of last mail update 
  2997. X            {
  2998. X                if (fistat.st_mtime != mail_check &&
  2999. X                fistat.st_size > mail_size)    // new mail (mailbox bigger)
  3000. X                {
  3001. X                    return(1);
  3002. X                }
  3003. X                mail_check = fistat.st_mtime;
  3004. X                mail_size = fistat.st_size;
  3005. X            }
  3006. X        }
  3007. X    }
  3008. X    return(0);
  3009. X};
  3010. X
  3011. X// Function:    save
  3012. X// Purpose:        save the current User to the User file
  3013. X// Input:        path - the path to the User file
  3014. X// Output:        returns non-zero on failure
  3015. X// Author:        Greg Shaw
  3016. X// Created:        6/5/93
  3017. X
  3018. Xint User::save(char *name)
  3019. X{
  3020. X    FILE    *ufile;
  3021. X    FILE    *ofile;
  3022. X    char    finame[255];        // filename
  3023. X    char    line[255];        // one line in file (255 max)
  3024. X    char    bbspath[225];    // bbs path
  3025. X    char    logname[10];    // user login name
  3026. X    char    found;            // user found?
  3027. X    char    linenum;        // used to look for appropriate line
  3028. X    char    c;                // input character
  3029. X    char    *u;
  3030. X    unsigned char    of;        // offset into line
  3031. X    int    x;
  3032. X    time_t    now;
  3033. X
  3034. X    last_login = login_time;    // set to new login time
  3035. X    time(&now);
  3036. X    timeused += (now - login_time)/60;    // update time used field.
  3037. X    if (name == NULL)
  3038. X        strcpy(logname,username());        // get user's log information    
  3039. X    else
  3040. X        strcpy(logname,name);
  3041. X    if (strcpy(bbspath,getenv("BBSDIR")), bbspath == NULL)
  3042. X    {
  3043. X        sprintf(finame,"user.save: BBSDIR env var not set for %s",logname);
  3044. X        ap_log(finame);
  3045. X        return(-1);
  3046. X    }
  3047. X    strcpy(line,bbspath);
  3048. X    strcat(line,"/admin/nuserlog");
  3049. X    if (ofile = bopen(line,"w"), ofile == NULL)
  3050. X    {
  3051. X        sprintf(line,"user.save: Unable to open new userlog file: %s",logname);
  3052. X        ap_log(line);
  3053. X        return(-1);
  3054. X    }    
  3055. X    chmod(line,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); // change permissions
  3056. X    strcpy(finame,bbspath);
  3057. X    strcat(finame,"/admin/userlog");
  3058. X    linenum = 0;        // look for first line first
  3059. X    if (ufile = bopen(finame,"r"), ufile == NULL)
  3060. X    {
  3061. X        // create the bugger so that you can continue
  3062. X        ufile = bopen(finame,"w");
  3063. X        bclose(ufile);
  3064. X        if (ufile = bopen(finame,"r"), ufile == NULL)
  3065. X        {    // still can't open the file!  AARGH!
  3066. X            sprintf(line,"user.save: Unable to open userlog file.",logname);
  3067. X            ap_log(line);
  3068. X            return(-1);
  3069. X        }
  3070. X    }
  3071. X    else
  3072. X    {
  3073. X        found = 0;
  3074. X        while (!found && !feof(ufile))
  3075. X        {
  3076. X            // get first line
  3077. X            of = 0;
  3078. X            while (c = fgetc(ufile), c != '\r' && c != '\n' && !feof(ufile))
  3079. X                if (c != ']')    // skip trailing left bracket
  3080. X                    line[of++] = c;
  3081. X            line[of] = 0;    // add null
  3082. X            if (!feof(ufile) && of > 1)    // end of file, skip.
  3083. X            {
  3084. X                switch(linenum)
  3085. X                {
  3086. X                case 0:    // first line
  3087. X                    if (line[0] == '[' && line[1] == 'A')    // got line 1?
  3088. X                    {
  3089. X                        x = sscanf(&line[2],"%s %s %s %s %s %s",login_name,
  3090. X                            fname, lname, alias, state, city);
  3091. X                        if (u = strchr(city,']'), u != NULL)
  3092. X                        {    // convert any left brackets to null
  3093. X                            u++;
  3094. X                            u[0] = 0;
  3095. X                        }
  3096. X                        if (strcmp(login_name,logname) == 0)
  3097. X                        {
  3098. X                            linenum++;        // get next line
  3099. X                            fprintf(ofile,"[A %s %s %s %s %s %s ]\n", login_name, fname, lname, alias, state, city);
  3100. X                        }
  3101. X                        else
  3102. X                            fprintf(ofile,"%s]\n",line);
  3103. X    //                    [A login_name firstname lastname state city]
  3104. X                    }
  3105. X                    else
  3106. X                        fprintf(ofile,"%s]\n",line);
  3107. X                    break;
  3108. X                case 1:    // second line
  3109. X                    if (line[0] == '[' && line[1] == 'B')    // got line 2?
  3110. X                    {
  3111. X                            fprintf(ofile,"[B %s %ld %d %d %d %s ]\n", uterm, 
  3112. X                                last_login, logins, downloads, uploads, card->colr);
  3113. X    //                    [B terminal_type last_logon #_logins downloads uploads]
  3114. X                        linenum++;        // get next line
  3115. X                    }
  3116. X                    else
  3117. X                        fprintf(ofile,"%s]\n",line);
  3118. X                    break;
  3119. X                case 2:    // third line
  3120. X                    if (line[0] == '[' && line[1] == 'C')    // got line 3?
  3121. X                    {
  3122. X                        fprintf(ofile,"[C %d %d %d %d %s %d %d]\n",priv_msgs,
  3123. X                            pub_msgs, credited, has_color, editor, lines, cols);
  3124. X                        linenum++;        // save next line
  3125. X    //                    [C private_msgs public_msgs credited_time has_color editor lines cols]
  3126. X                    }
  3127. X                    else
  3128. X                        fprintf(ofile,"%s]\n",line);
  3129. X                    break;
  3130. X                case 3:    // fourth line
  3131. X                    if (line[0] == '[' && line[1] == 'D')    // got line 4?
  3132. X                    {
  3133. X                        fprintf(ofile,"[D %lx %d %d %d %ld %d ]\n",
  3134. X                            flags, acl, timelimit, timeused,anniversary,kused);
  3135. X    //                    [D flags access_level timelimit timeused_last_call anniversary kused ]
  3136. X                        linenum++;        // save next line
  3137. X                    }
  3138. X                    else
  3139. X                        fprintf(ofile,"%s]\n",line);
  3140. X                    break;
  3141. X                }    
  3142. X                if (linenum == 4)    // got him.
  3143. X                {
  3144. X                    found++;
  3145. X                }
  3146. X            }
  3147. X        }
  3148. X        // Ok, got the guy.  copy the rest of the file
  3149. X        while (!feof(ufile))
  3150. X        {
  3151. X            c = fgetc(ufile);
  3152. X            if (!feof(ufile))
  3153. X                fputc(c,ofile);
  3154. X        }
  3155. X    }
  3156. X    // now rename the userfile to old userfile
  3157. X    bclose(ufile);
  3158. X    bclose(ofile);
  3159. X    strcpy(line,bbspath);
  3160. X    strcat(line,"/admin/userlog.old");
  3161. X    if (rename(finame, line) != 0)
  3162. X    {
  3163. X        sprintf(finame,"user.save: unable to rename userlog to userlog.old");
  3164. X        ap_log(finame);
  3165. X        return(-1);
  3166. X    }    
  3167. X    strcpy(line,bbspath);
  3168. X    strcat(line,"/admin/nuserlog");
  3169. X    strcpy(finame,bbspath);
  3170. X    strcat(finame,"/admin/userlog");
  3171. X    if (rename(line, finame) != 0)
  3172. X    {
  3173. X        sprintf(finame,"user.save: unable to rename new userlog to userlog",logname);
  3174. X        ap_log(finame);
  3175. X        return(-1);
  3176. X    }    
  3177. X    chmod(finame,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); // change permissions
  3178. X    return(0);
  3179. X}
  3180. X
  3181. X// Function:        sysop_edit
  3182. X// Purpose:        allow the sysop to edit a user
  3183. X// Input:        firsttime - is this the first logon by user?
  3184. X// Output:        (user questions)
  3185. X// Author:        Greg Shaw
  3186. X// Created:        4/11/94
  3187. X
  3188. Xint User::sysop_edit(void)
  3189. X{
  3190. X    char     c;
  3191. X    char    loop;            // loop counter
  3192. X    char    changed;        // changed anything?
  3193. X    char    tmpstr[255];
  3194. X    char    str1[50], str2[50];
  3195. X    int    selected;        // which selected?
  3196. X    int    tmp;
  3197. X    int    x;
  3198. X    struct tm *tmdata;        // time stuff
  3199. X
  3200. X    loop = 1;
  3201. X    changed = 0;
  3202. X    while (loop)
  3203. X    {
  3204. X        clear();        // clear screen
  3205. X        cr();
  3206. X        cr();
  3207. X        cr();
  3208. X        sstrcr("Current User Statistics:");
  3209. X        cr();
  3210. X        sprintf(tmpstr,"Login: %s   Full Name: %s %s from %s, %s",login_name,fname,lname,city,state);
  3211. X        sstrcr(tmpstr);
  3212. X        sprintf(tmpstr,"Alias: %s   Downloads: %d   Uploads %d   Number of Logons: %d ",alias, downloads, uploads, logins);
  3213. X        sstrcr(tmpstr);
  3214. X        sprintf(tmpstr,"ACL: %d   Flags(hex): 0x%8.8lx   Timelimit: %d minutes",acl, flags, timelimit);
  3215. X        sstrcr(tmpstr);
  3216. X        sprintf(tmpstr,"Terminal Type: %s   Card Color: %s   Lines: %d   Columns %d",uterm,card->colr,lines,cols);
  3217. X        sstrcr(tmpstr);
  3218. X        tmdata = localtime(&anniversary);
  3219. X        strftime(str1,49,"%c",tmdata);
  3220. X        tmdata = localtime(&last_login);
  3221. X        strftime(str2,49,"%c",tmdata);
  3222. X        sprintf(tmpstr,"First Logon: %s",str1);
  3223. X        sstrcr(tmpstr);
  3224. X        sprintf(tmpstr,"Last Logon:  %s for %d minutes",str2,timeused);
  3225. X        sstrcr(tmpstr);
  3226. X        sstr("Is this correct? ");
  3227. X        if (yesno())
  3228. X        {
  3229. X            if (changed)
  3230. X            {
  3231. X                sstrcr("Saving user information...");
  3232. X                save(login_name); 
  3233. X            }
  3234. X            return(0);
  3235. X        }
  3236. X        clear();
  3237. X        sstrcr("You may edit the following: ");
  3238. X        sstrcr("1.  Login Name        2.  First Name");
  3239. X        sstrcr("3.  Last Name        4.  City");
  3240. X        sstrcr("5.  State        6.  Alias");
  3241. X        sstrcr("7.  Downloads        8.  Uploads");
  3242. X        sstrcr("9.  Access Level    10. Flags");
  3243. X        sstrcr("11. Timelimit        12. Terminal Type");
  3244. X        sstrcr("13. Card Color        14. Lines");
  3245. X        sstrcr("15. Columns");
  3246. X        sstrcr("Press return to exit.");
  3247. X        cr();
  3248. X        sstr("Edit which? ");
  3249. X        gstr(str1,3);
  3250. X        selected = 0;
  3251. X        if (sscanf(str1,"%d",&selected) != 1 || (selected < 1 || selected > 15))
  3252. X            continue;
  3253. X        switch(selected)
  3254. X        {
  3255. X        case 1:    //  get login name
  3256. X            sstrcr("Login name change hasn't been done yet.");
  3257. X            sstrcr("It would require /etc/passwd modifications.");
  3258. X            sstrcr("Which would be a security hole.");
  3259. X            waitcr();
  3260. X            break;  // not done at this time (requires
  3261. X                // modification of passwd file)
  3262. X        case 2: // get first name
  3263. X            sprintf(tmpstr,"Current first name: %s",fname);    
  3264. X            sstrcr(tmpstr);
  3265. X            cr();
  3266. X            sstrcr("Press return to exit.");
  3267. X            cr();
  3268. X            sstr("Change first name to? ");
  3269. X            gstr(str1,20);
  3270. X            if (sscanf(str1,"%s",str2) != 1)
  3271. X            {
  3272. X                sstrcr("Not changed.");
  3273. X                waitcr();
  3274. X                continue;
  3275. X            }
  3276. X            strcpy(fname,str2);
  3277. X            changed++;
  3278. X            break;
  3279. X        case 3: // get last name
  3280. X            sprintf(tmpstr,"Current last name: %s",lname);    
  3281. X            sstrcr(tmpstr);
  3282. X            cr();
  3283. X            sstrcr("Press return to exit.");
  3284. X            cr();
  3285. X            sstr("Change last name to? ");
  3286. X            gstr(str1,20);
  3287. X            if (sscanf(str1,"%s",str2) != 1)
  3288. X            {
  3289. X                sstrcr("Not changed.");
  3290. X                waitcr();
  3291. X                continue;
  3292. X            }
  3293. X            strcpy(lname,str2);
  3294. X            changed++;
  3295. X            break;
  3296. X        case 4: // get city
  3297. X            sprintf(tmpstr,"Current city: %s",city);    
  3298. X            sstrcr(tmpstr);
  3299. X            cr();
  3300. X            sstrcr("Press return to exit.");
  3301. X            cr();
  3302. X            sstr("Change city to? ");
  3303. X            gstr(str1,20);
  3304. X            if (sscanf(str1,"%s",str2) != 1)
  3305. X            {
  3306. X                sstrcr("Not changed.");
  3307. X                waitcr();
  3308. X                continue;
  3309. X            }
  3310. X            strcpy(city,str2);
  3311. X            changed++;
  3312. X            break;
  3313. X        case 5: // get state
  3314. X            sprintf(tmpstr,"Current state: %s",state);    
  3315. X            sstrcr(tmpstr);
  3316. X            cr();
  3317. X            sstrcr("Press return to exit.");
  3318. X            cr();
  3319. X            sstr("Change state to? ");
  3320. X            gstr(str1,14);
  3321. X            if (sscanf(str1,"%s",str2) != 1)
  3322. X            {
  3323. X                sstrcr("Not changed.");
  3324. X                waitcr();
  3325. X                continue;
  3326. X            }
  3327. X            strcpy(state,str2);
  3328. X            changed++;
  3329. X            break;
  3330. X        case 6: // get alias
  3331. X            sprintf(tmpstr,"Current alias: %s",alias);    
  3332. X            sstrcr(tmpstr);
  3333. X            cr();
  3334. X            sstrcr("Press return to exit.");
  3335. X            cr();
  3336. X            sstr("Change alias to? ");
  3337. X            gstr(str1,20);
  3338. X            if (sscanf(str1,"%s",str2) != 1)
  3339. X            {
  3340. X                sstrcr("Not changed.");
  3341. X                waitcr();
  3342. X                continue;
  3343. X            }
  3344. X            strcpy(alias,str2);
  3345. X            changed++;
  3346. X            break;
  3347. X        case 7: // get downloads
  3348. X            sprintf(tmpstr,"Current downloads: %d",downloads);    
  3349. X            sstrcr(tmpstr);
  3350. X            cr();
  3351. X            sstrcr("Press return to exit.");
  3352. X            cr();
  3353. X            sstr("Change downloads to? ");
  3354. X            gstr(str1,4);
  3355. X            if (sscanf(str1,"%d",&tmp) != 1)
  3356. X            {
  3357. X                sstrcr("Not changed.");
  3358. X                waitcr();
  3359. X                continue;
  3360. X            }
  3361. X            downloads = tmp;
  3362. X            changed++;
  3363. X            break;
  3364. X        case 8: // get uploads
  3365. X            sprintf(tmpstr,"Current downloads: %d",downloads);    
  3366. X            sstrcr(tmpstr);
  3367. X            cr();
  3368. X            sstrcr("Press return to exit.");
  3369. X            cr();
  3370. X            sstr("Change downloads to? ");
  3371. X            gstr(str1,4);
  3372. X            if (sscanf(str1,"%d",&tmp) != 1)
  3373. X            {
  3374. X                sstrcr("Not changed.");
  3375. X                waitcr();
  3376. X                continue;
  3377. X            }
  3378. X            downloads = tmp;
  3379. X            changed++;
  3380. X            break;
  3381. X        case 9: // get access level
  3382. X            sprintf(tmpstr,"Current access level: %d",acl);    
  3383. X            sstrcr(tmpstr);
  3384. X            cr();
  3385. X            sstrcr("Press return to exit.");
  3386. X            cr();
  3387. X            sstr("Change access level to? ");
  3388. X            gstr(str1,5);
  3389. X            if (sscanf(str1,"%d",&tmp) != 1)
  3390. X            {
  3391. X                sstrcr("Not changed.");
  3392. X                waitcr();
  3393. X                continue;
  3394. X            }
  3395. X            acl = tmp;
  3396. X            changed++;
  3397. X            break;
  3398. X        case 10: // get flags
  3399. X            sstrcr("Current flags:");    
  3400. X            for (x=0; x<32; x++)
  3401. X            {
  3402. X                if (x%8 == 0 && x != 0)
  3403. X                    cr();
  3404. X                sprintf(tmpstr,"%.2d:%d ",x,flags&1<<x?1:0);
  3405. X                sstr(tmpstr);
  3406. X            }
  3407. X            cr();
  3408. X            sstrcr("Press return to exit.");
  3409. X            cr();
  3410. X            sstr("Set or Clear a flag? ");
  3411. X            gstr(str1,2);
  3412. X            for (c=0; c<strlen(str1); c++)
  3413. X                str1[c] = tolower(str1[c]);
  3414. X            if (strchr(str1,'s') != NULL)
  3415. X            {
  3416. X                sstr("Set which flag? (0-31) ");
  3417. X                gstr(str1,3);
  3418. X                if (sscanf(str1,"%d",&tmp) != 1 || (tmp < 0 || tmp > 31))
  3419. X                {
  3420. X                    sstrcr("Not changed.");
  3421. X                    waitcr();
  3422. X                    continue;
  3423. X                } 
  3424. X                flags |= 1<<tmp;
  3425. X            } 
  3426. X            else if (strchr(str1,'c') != NULL)
  3427. X            {
  3428. X                sstr("Clear which flag? (0-31) ");
  3429. X                gstr(str1,3);
  3430. X                if (sscanf(str1,"%d",&tmp) != 1 || (tmp < 0 || tmp > 31))
  3431. X                {
  3432. X                    sstrcr("Not changed.");
  3433. X                    waitcr();
  3434. X                    continue;
  3435. X                } 
  3436. X                flags &= ~(1<<tmp);
  3437. X            }
  3438. X            else
  3439. X            {
  3440. X                sstrcr("Not changed.");
  3441. X                waitcr();
  3442. X                continue;
  3443. X            } 
  3444. X            changed++;
  3445. X            break;
  3446. X        case 11: // get timelimit
  3447. X            sprintf(tmpstr,"Current timelimit: %d",timelimit);    
  3448. X            sstrcr(tmpstr);
  3449. X            cr();
  3450. X            sstrcr("Press return to exit.");
  3451. X            cr();
  3452. X            sstr("Change timelimit to? ");
  3453. X            gstr(str1,5);
  3454. X            if (sscanf(str1,"%d",&tmp) != 1)
  3455. X            {
  3456. X                sstrcr("Not changed.");
  3457. X                waitcr();
  3458. X                continue;
  3459. X            }
  3460. X            timelimit = tmp;
  3461. X            changed++;
  3462. X            break;
  3463. X        case 12: // get terminal types
  3464. X            sprintf(tmpstr,"Current terminal type: %s",uterm);    
  3465. X            sstrcr(tmpstr);
  3466. X            cr();
  3467. X            sstrcr("Press return to exit.");
  3468. X            cr();
  3469. X            sstr("Change terminal type to? ");
  3470. X            gstr(str1,20);
  3471. X            if (sscanf(str1,"%s",str2) != 1)
  3472. X            {
  3473. X                sstrcr("Not changed.");
  3474. X                waitcr();
  3475. X                continue;
  3476. X            }
  3477. X            strcpy(uterm,str2);
  3478. X            changed++;
  3479. X            break;
  3480. X        case 13: // get card color
  3481. X            sprintf(tmpstr,"Current card color: %s",card->colr);    
  3482. X            sstrcr(tmpstr);
  3483. X            cr();
  3484. X            sstrcr("Press return to exit.");
  3485. X            cr();
  3486. X            sstr("Change card color to? ");
  3487. X            gstr(str1,10);
  3488. X            if (sscanf(str1,"%s",str2) != 1)
  3489. X            {
  3490. X                sstrcr("Not changed.");
  3491. X                waitcr();
  3492. X                continue;
  3493. X            }
  3494. X            for (c = 0; c < strlen(str2); c++) // convert to lower case
  3495. X                str2[c] = tolower(str2[c]);
  3496. X            if (!strcmp(str2,"red"))
  3497. X                card_color = 0;
  3498. X            else if (!strcmp(str2,"blue"))
  3499. X                card_color = 1;
  3500. X            else if (!strcmp(str2,"green"))
  3501. X                card_color = 2;
  3502. X            else if (!strcmp(str2,"white"))
  3503. X                card_color = 3;
  3504. X            else if (!strcmp(str2,"grey"))
  3505. X                card_color = 4;
  3506. X            else if (!strcmp(str2,"pink"))
  3507. X                card_color = 5;
  3508. X            else if (!strcmp(str2,"yellow"))
  3509. X                card_color = 6;
  3510. X            else if (!strcmp(str2,"black"))
  3511. X                card_color = 7;
  3512. X            else
  3513. X            {
  3514. X                sstrcr("Unable to determine card color.");
  3515. X                sstrcr("Card color unchanged.");
  3516. X                waitcr();
  3517. X                continue;
  3518. X            }
  3519. X            check_card();
  3520. X            changed++;
  3521. X            break;
  3522. X        case 14: // get lines
  3523. X            sprintf(tmpstr,"Current lines: %d",lines);    
  3524. X            sstrcr(tmpstr);
  3525. X            cr();
  3526. X            sstrcr("Press return to exit.");
  3527. X            cr();
  3528. X            sstr("Change lines to? ");
  3529. X            gstr(str1,4);
  3530. X            if (sscanf(str1,"%d",&tmp) != 1)
  3531. X            {
  3532. X                sstrcr("Not changed.");
  3533. X                waitcr();
  3534. X                continue;
  3535. X            }
  3536. X            lines = tmp;
  3537. X            changed++;
  3538. X            break;
  3539. X        case 15: // get columns
  3540. X            sprintf(tmpstr,"Current columns : %d",cols);    
  3541. X            sstrcr(tmpstr);
  3542. X            cr();
  3543. X            sstrcr("Press return to exit.");
  3544. X            cr();
  3545. X            sstr("Change columns to? ");
  3546. X            gstr(str1,4);
  3547. X            if (sscanf(str1,"%d",&tmp) != 1)
  3548. X            {
  3549. X                sstrcr("Not changed.");
  3550. X                waitcr();
  3551. X                continue;
  3552. X            }
  3553. X            cols = tmp;
  3554. X            changed++;
  3555. X            break;
  3556. X        }
  3557. X    }
  3558. X    return(0);
  3559. X};
  3560. X// Function:    constructor
  3561. X// Purpose:        initialize all object variables
  3562. X// Input:        none
  3563. X// Output:        (object is initialized)
  3564. X// Author:        Greg Shaw
  3565. X// Created:        6/1/93
  3566. X
  3567. XUser::User()
  3568. X{
  3569. X    card = NULL;
  3570. X    if (card_color = def_card(), card_color == -1)
  3571. X        ap_log("Unable to get default card color.");
  3572. X    if (card_color != -1 && (card = cardinfo(card_color), card == NULL))
  3573. X        ap_log("Unable to get card information.");
  3574. X    fname[0] = 0;
  3575. X    lname[0] = 0;
  3576. X    alias[0] = 0;
  3577. X    login_name[0] = 0;
  3578. X    editor[0] = 0;
  3579. X    city[0] = 0;
  3580. X    state[0] = 0;
  3581. X    uterm[0] = 0;
  3582. X    time(&last_login);
  3583. X    time(&login_time);
  3584. X    time(&anniversary);
  3585. X    mail_check = 0;
  3586. X    logins = 1;
  3587. X    lines = 24;
  3588. X    cols = 80;
  3589. X    downloads = 0;
  3590. X    uploads = 0;
  3591. X    priv_msgs = 0;
  3592. X    pub_msgs = 0;
  3593. X    credited = 0;
  3594. X    flags = 0;
  3595. X    tmpflags = 0;
  3596. X    acl = card->acl;
  3597. X    tmpacl = acl;
  3598. X    timelimit = card->tl;
  3599. X    tmptl = timelimit;
  3600. X    credited = 0;
  3601. X    timeused = 0;
  3602. X    kused = 0;
  3603. X    has_color = 0;
  3604. X}
  3605. X
  3606. X// Function:    destructor
  3607. X// Purpose:        clean up the object
  3608. X// Input:        none
  3609. X// Output:        none ( null destructor at this point )
  3610. X// Author:        Greg Shaw
  3611. X// Created:        6/1/93
  3612. X
  3613. XUser::~User()
  3614. X{
  3615. X}
  3616. X#endif // _USER_C_
  3617. END_OF_FILE
  3618.   if test 45033 -ne `wc -c <'rocat-0.75/src/user.C'`; then
  3619.     echo shar: \"'rocat-0.75/src/user.C'\" unpacked with wrong size!
  3620.   fi
  3621.   chmod +x 'rocat-0.75/src/user.C'
  3622.   # end of 'rocat-0.75/src/user.C'
  3623. fi
  3624. echo shar: End of archive 4 \(of 9\).
  3625. cp /dev/null ark4isdone
  3626. MISSING=""
  3627. for I in 1 2 3 4 5 6 7 8 9 ; do
  3628.     if test ! -f ark${I}isdone ; then
  3629.     MISSING="${MISSING} ${I}"
  3630.     fi
  3631. done
  3632. if test "${MISSING}" = "" ; then
  3633.     echo You have unpacked all 9 archives.
  3634.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3635. else
  3636.     echo You still must unpack the following archives:
  3637.     echo "        " ${MISSING}
  3638. fi
  3639. exit 0
  3640. exit 0 # Just in case...
  3641.