home *** CD-ROM | disk | FTP | other *** search
/ World of Ham Radio 1994 January / AMSOFT_1994.iso / packet / pbbs / cbbs / prog / mbuser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-31  |  13.2 KB  |  625 lines

  1.  
  2. /*
  3.  *  MBUSER.C - 6/10/88
  4.  */
  5.  
  6. #include "mb.h"
  7.  
  8. #define uf_inc 100    /* Headroom in user file */
  9.  
  10. char *usfile, *usbfile;
  11. USER_HDR *ufhs;
  12. USER     *tuser;
  13. char   *um[num_um];
  14. char   tcall[ln_call];
  15. short  maxusers;
  16. static char *users;
  17.  
  18. int ufl;
  19.  
  20. /*
  21.  *  Clean the user file.
  22.  *  Force drain of buffers, update of directory items.
  23.  */
  24.  
  25. clnuser()
  26. {
  27.   close(ufl);
  28.   ufl = open(usfile, O_RDWR | O_BINARY);
  29. }
  30.  
  31. /*
  32.  *  Close the user file.
  33.  */
  34.  
  35. clsusr()
  36. {
  37.   close (ufl);
  38. }
  39.  
  40. /*
  41.  *  Open the user file.
  42.  *  Allocate space for the user file records.
  43.  */
  44.  
  45. opnusr()
  46. {
  47.   ufhs = (USER_HDR *) malloc(sizeof(USER_HDR));
  48.  
  49.   tuser = (USER *) malloc(sizeof(USER));
  50.   tuser->rn = 0;
  51.  
  52. /*
  53.  *  Open the file. If it does not exist, make one.
  54.  */
  55.  
  56.   ufl = open(usfile, O_RDWR | O_BINARY);
  57.   if (ufl < 0)
  58.   {
  59.     ufl = open(usfile, O_CREAT | O_RDWR | O_BINARY, pmode);
  60.     if (ufl < 0) { nofile(usfile); exit(1); }
  61.     inuhdr();
  62.     write_rec(ufl, 0, (char *)ufhs);
  63.   }
  64.  
  65. /*
  66.  *  Read the user calls.
  67.  */
  68.  
  69.   read_rec(ufl, 0, (char *)ufhs);
  70.  
  71.   if (ufhs->version isnt us_version)
  72.   {
  73.     printf("Expected version %d, got version %d\n", us_version, ufhs->version);
  74.     nofile(usfile);
  75.     exit(1);
  76.   }
  77.  
  78.   maxusers = ufhs->count + uf_inc;
  79.  
  80.   users = (char *) malloc(ln_call * maxusers);
  81.   if (users is NULL) errall();
  82.  
  83.   rdusers();
  84. }
  85.  
  86. /*
  87.  *  Open the user file and read record zero
  88.  */
  89.  
  90. readusr()
  91. {
  92.   short prev_cnt;
  93.  
  94.   prev_cnt = ufhs->count;
  95.   ufl = open(usfile, O_RDWR | O_BINARY);
  96.   read_rec (ufl, 0, (char*)ufhs);
  97.   if (ufhs->count isnt prev_cnt) rdusers();
  98. }
  99.  
  100. /*
  101.  *  Read each user record, build list of calls.
  102.  */
  103.  
  104. rdusers()
  105. {
  106.   register int i;
  107.   register char *up;
  108.  
  109.   printf("%d users in %s\n", ufhs->count, usfile);
  110.  
  111.   for (i = 1, up = users; i <= ufhs->count; i++, up += ln_call)
  112.   {
  113.     read_rec(ufl, i, (char *)tuser);
  114.     strncpy(up, tuser->call, ln_call);
  115.     if (!tuser->zip) fill(tuser->zip, ' ', ln_zip);
  116.   }
  117.  
  118. }
  119.  
  120. /*
  121.  *  initialize the user file header.
  122.  */
  123.  
  124. inuhdr()
  125. {
  126.   curtim();
  127.   ufhs->count = 0;
  128.   ufhs->version = us_version;
  129.   strncpy(ufhs->date, l_date, ln_date);
  130.   strncpy(ufhs->time, l_time, ln_time);
  131.   ufhs->lmnr = mfhs->next_msg - 1;
  132.   fill (ufhs->unu, '\0', ufhsunu);
  133. }
  134.  
  135. /*
  136.  *  Do we know this user?
  137.  */
  138.  
  139. finduser(call)
  140. char *call;
  141. {
  142.   register int i;
  143.   register char *up;
  144.  
  145.   for (i = 1, up = users; i <= ufhs->count; i++, up += ln_call)
  146.   if (matchn(call, up, ln_call)) return i;
  147.  
  148.   return 0;
  149. }
  150.  
  151. /*
  152.  *  Read in a user record.
  153.  */
  154.  
  155. rduser(call, buf)
  156. char *call;
  157. USER *buf;
  158. {
  159.   register int i;
  160.  
  161.   if (i = finduser(call))
  162.   {
  163.     read_rec(ufl, i, (char *)buf);
  164.     buf->rn = i;
  165.     return i;
  166.   }
  167.  
  168. /*
  169.  *  There wasn't one, make one.
  170.  */
  171.  
  172.   curtim();
  173.  
  174.   buf->rn = 0;  /* Mark as non current record */
  175.  
  176.   strncpy(buf->call, call,   ln_call);
  177.   strncpy(buf->date, l_date, ln_date);
  178.   strncpy(buf->time, l_time, ln_time);
  179.  
  180.   buf->msg_number = 0;
  181.   buf->ssid       = 0;
  182.   buf->state      = 0;
  183.   buf->options    = 0;
  184.   buf->log_count  = 0;
  185.   buf->port       = ' ';
  186.  
  187.   ljsf(buf->handle, um[0], ln_handle);
  188.  
  189.   fill(buf->path, ' ', pathl);
  190.   *buf->path = '\0';
  191.  
  192.   fill(buf->home_bbs, ' ', ln_call);
  193.   fill(buf->zip,      ' ', ln_zip);
  194.   fill(buf->unu,        0, userunu);
  195.  
  196.   return 0;
  197. }
  198.  
  199. /*
  200.  *  Update the user record to the file.
  201.  */
  202.  
  203. upduser(buf)
  204. USER *buf;
  205. {
  206.   if (s_flag & s_dv) begin_lock();
  207.   read_rec(ufl, 0, (char*)ufhs);
  208.   if (!buf->rn)
  209.   {
  210.     if (ufhs->count >= maxusers)
  211.       {
  212.         if (s_flag & s_dv) end_lock();
  213.         return;
  214.       }
  215.     strncpy (users + (ln_call * ufhs->count), buf->call, ln_call);
  216.     buf->rn = ++ufhs->count;
  217.   }
  218.  
  219.   curtim();
  220.   strncpy(buf->date, l_date, ln_date);
  221.   strncpy(buf->time, l_time, ln_time);
  222.   if (s_flag & s_update)
  223.     {
  224.       buf->msg_number = mfhs->next_msg;
  225.       s_flag clrbit s_update;
  226.     }
  227.   buf->log_count++;
  228.   write_rec(ufl, buf->rn, (char *)buf);
  229.   write_rec(ufl, 0, (char *)ufhs);
  230.   if (s_flag & s_dv) end_lock();
  231. }
  232.  
  233. /*
  234.  *  Print info about a user.
  235.  */
  236.  
  237. puser()
  238. {
  239.   register int i;
  240.   register PORTS *p;
  241.  
  242.   pcall(tcall, port->fld[1]);
  243.   if (!(i = finduser(tcall))) { port->msg = mfind; return; }
  244.  
  245.   read_rec(ufl, i, (char *)tuser);
  246.  
  247.   if ((p = findport(tuser->port)) is NULL)
  248.     sprintf( tmp->scr, "Port %c\n", tuser->port);
  249.   else
  250.     sprintf(tmp->scr, "%s\n", p->name);
  251.   if(tuser->port isnt 'L')
  252.   {
  253.     outnb(tuser->call, ln_call);
  254.     outstr(" connected on ");
  255.     outstr(tmp->scr);
  256.   }
  257.   outnb(tuser->call, ln_call);
  258.   if (tuser->port is 'L')
  259.   {
  260.     outstr(" Linked to "); outnb(cport->user->call, ln_call);
  261.     outstr(" Through the GateWay at "); outstr(tuser->path);
  262.   }
  263.   else if (!*tuser->path)
  264.   {
  265.     outstr(" is a direct connect from "); outnb(cport->user->call, ln_call);
  266.   }
  267.   else
  268.   {
  269.     outstr(" connected to "); outnb(cport->user->call, ln_call);
  270.     outstr(" via "); outstr(tuser->path);
  271.   }
  272.   outchar('\n');
  273.  
  274.   outnb(tuser->call, ln_call);
  275.   sprintf(tmp->scr, " Last connected on %6.6s at %4.4s\n",
  276.     tuser->date, tuser->time);
  277.   outstr(tmp->scr);
  278.  
  279.   outstr("Name - ");
  280.   outnb(tuser->handle, ln_handle);
  281.  
  282.   if (tuser->state & u_home)
  283.   {
  284.     outstr(", Mail bbs - ");
  285.     outnb(tuser->home_bbs, ln_call);
  286.   }
  287.  
  288.   if (tuser->state & u_zip)
  289.   {
  290.     outstr(", Zip - ");
  291.     outnb(tuser->zip, ln_zip);
  292.   }
  293.     outchar('\n');
  294. }
  295.  
  296. /*
  297.  *  Print a user record.
  298.  */
  299.  
  300. prtuser(p)
  301. USER *p;
  302. {
  303.   fill(port->cmd, ' ', 6);
  304.   if (p->options & u_local)   port->cmd[0] = 'L';
  305.   if (p->options & u_bbs)     port->cmd[1] = 'B';
  306.   if (p->options & u_expert)  port->cmd[2] = 'E';
  307.   if (p->options & u_delete)  port->cmd[3] = 'D';
  308.   if (p->options & u_sysop)   port->cmd[4] = 'S';
  309.   if (p->options & u_exclude) port->cmd[5] = 'K';
  310.   sprintf(tmp->scr,
  311.   "%6.6s %6.6s %4.4s %4d %5u %6.6s %2.2d%c%6.6s %-12.12s %6.6s\n  Path: %s\n",
  312.     p->call, p->date, p->time, p->log_count,
  313.     p->msg_number, p->home_bbs, p->ssid,
  314.     p->port, port->cmd, p->handle, p->zip, p->path);
  315.  
  316.   outstr(tmp->scr);
  317. }
  318.  
  319. /*
  320.  *  The "display users" command.
  321.  */
  322.  
  323. duser()
  324. {
  325.   register int i;
  326.   register short ok;
  327.  
  328.   if (port->flds is 1) pgst(um[2]); else
  329.   {
  330.     if ((port->fl = fopen(port->fld[1], "r")) isnt NULL)
  331.     { fclose(port->fl); port->msg = mexst; return; }
  332.     if ((port->fl = fopen(port->fld[1], "w")) is NULL)
  333.     { port->msg = mcant; return; }
  334.   }
  335.  
  336.   for (i = ufhs->count; i; i--)
  337.   {
  338.     read_rec(ufl, i, (char *)tuser);
  339.     ok = false;
  340.     switch(port->opt2)
  341.     {
  342.       case 'L' : ok = (tuser->options & u_local);  break;
  343.       case 'M' : ok = (tuser->options & u_bbs);    break;
  344.       case 'S' : ok = (tuser->options & u_sysop);  break;
  345.       case 'U' : ok = true; break;
  346.       case 'X' : ok = (tuser->options & u_exclude); break;
  347.     }
  348.  
  349.     if (ok)
  350.     {
  351.       if (port->flds is 1)
  352.       {
  353.         pghd();
  354.         prtuser(tuser);
  355.         if (pgck() is 'Q') return;
  356.         if (pgck() is 'Q') return;
  357.       }
  358.       else
  359.       {
  360.         prtuser(tuser);
  361.         fprintf(port->fl, "%s", tmp->scr);
  362.       }
  363.     }
  364.   }
  365.   if (port->flds is 1) pgdn(); else fclose(port->fl);
  366. }
  367.  
  368. /*
  369.  *  The N, NE, NH, NZ (update my user info) commands.
  370.  */
  371.  
  372. chguser()
  373. {
  374.   switch(port->opt2)
  375.   {
  376.     case ' ' : ljsf(port->user->handle, port->line + 2, ln_handle);
  377.                port->user->state setbit u_name;
  378.                break;
  379.  
  380.     case 'E' : port->user->options flipbit u_expert;
  381.                break;
  382.  
  383.     case 'H' : pcall(port->user->home_bbs, port->fld[1]);
  384.  
  385.                if (matchn(port->user->home_bbs, cport->user->call, ln_call))
  386.                  port->user->options setbit u_local;
  387.                else port->user->options clrbit u_local;
  388.  
  389.                port->user->state setbit u_home;
  390.                port->user->state clrbit u_sent;
  391.                break;
  392.  
  393.     case 'Z' : ljsf(port->user->zip, port->fld[1], ln_zip);
  394.                port->user->state setbit u_zip;
  395.                port->user->state clrbit u_sent;
  396.                break;
  397.   }
  398.   port->msg = mdone;
  399. }
  400.  
  401. /*
  402.  *  EU command with no argument.
  403.  *  Loop through all users, ask delete for each one.
  404.  */
  405.  
  406. edusera()
  407. {
  408.   register word i;
  409.  
  410.   for (i = ufhs->count; i; i--)
  411.   {
  412.     read_rec(ufl, i, (char *)tuser);
  413.     if (tuser->rn isnt i)
  414.     {
  415.       sprintf(tmp->scr, "User record %u has record # %u\n", i, tuser->rn);
  416.       tuser->rn = i;
  417.     }
  418.  
  419.     prtx(um[2]);
  420.     prtuser(tuser);
  421.  
  422.     prtx(um[3]); getcmd();
  423.     if (port->mode & gone) return;
  424.     if (port->opt1 is 'Q') return;
  425.     if (port->opt1 is 'Y')
  426.     {
  427.       tuser->options |= u_delete;
  428.       write_rec(ufl, tuser->rn, (char *)tuser);
  429.     }
  430.   }
  431. }
  432.  
  433. /*
  434.  *  Edit a user record.
  435.  */
  436.  
  437. eduser()
  438. {
  439.   register USER *u;
  440.  
  441.   pcall(tcall, port->fld[1]);
  442.   if (matchn(tcall, port->user->call, ln_call)) u = port->user;
  443.   else { u = tuser; rduser(tcall, u); }
  444.   while(*port->fld[0] isnt '\0')
  445.   {
  446.     prtuser(u);
  447.     outstr("PRIVILEGE: (D)elete, (E)xpert, (B)bs, (S)ysop, e(X)clude\n");
  448.     outstr("DATA: (C)all, ss(I)d, (N)ame, por(T), (P)ath, (H)ome, (Z)ip\n");
  449.     getcmd();
  450.     if (port->mode & gone) return;
  451.     switch(*port->fld[0])
  452.     {
  453.       case 'D' : u->options flipbit u_delete; *port->fld[0] = '\0'; break;
  454.       case 'E' : u->options flipbit u_expert; break;
  455.       case 'B' : u->options flipbit u_bbs; break;
  456.       case 'S' : u->options flipbit u_sysop; break;
  457.       case 'X' : u->options flipbit u_exclude;break;
  458.       case 'C' : if (*port->fld[1]) pcall(u->call, port->fld[1]); break;
  459.       case 'I' : u->ssid = atoi(port->fld[1]); break;
  460.       case 'N' : if (*port->fld[1])
  461.                  {
  462.                    u->state setbit u_name;
  463.                    ljsf(u->handle, port->line+2, ln_handle);
  464.                  }
  465.                  break;
  466.       case 'T' : if (*port->fld[1]) u->port = *port->fld[1]; break;
  467.       case 'P' : if (port->fld[1]) strncpy(u->path, port->fld[1], pathl);
  468.                  else *u->path = '\0'; break;
  469.       case 'H' : if (*port->fld[1])
  470.                  {
  471.                    u->state setbit u_home;
  472.                    u->state clrbit u_sent;
  473.                    pcall(u->home_bbs, port->fld[1]);
  474.                    if (matchn(u->home_bbs, cport->user->call, ln_call))
  475.                    u->options setbit u_local; else u->options clrbit u_local;
  476.                  }
  477.                  else
  478.                  {
  479.                    fill(u->home_bbs, ' ', ln_call);
  480.                    u->options clrbit u_local;
  481.                    u->state clrbit u_home;
  482.                    u->state setbit u_sent;
  483.                  }
  484.                  break;
  485.       case 'Z' : if (*port->fld[1])
  486.                  {
  487.                    u->state setbit u_zip;
  488.                    u->state clrbit u_sent;
  489.                    ljsf(u->zip, port->fld[1], ln_zip);
  490.                  }
  491.                  else
  492.                  {
  493.                    fill(u->zip, ' ', ln_zip);
  494.                    u->state clrbit u_zip;
  495.                    u->state setbit u_sent;
  496.                  }
  497.                  break;
  498.     }
  499.   }
  500.  
  501. /*
  502.  *  If this is a new user, add to the list.
  503.  */
  504.  
  505.   upduser(u);
  506. }
  507.  
  508. /*
  509.  *  Backup the user file.
  510.  */
  511.  
  512. untuser()
  513. {
  514.   register char *rp, *wp, *lp;
  515.   register int uflb;
  516.   register int incnt, inrec;
  517.  
  518.   if (sure()) return;
  519.   prtx(um[1]);
  520.   lp = tmp->scr + (RECSIZE * (scrmax / RECSIZE));
  521.   upduser(port->user);
  522.   close(ufl);
  523.   unlink(usbfile);
  524.  
  525.   if (samedir(usfile, usbfile)) rename(usfile, usbfile);
  526.   else copy(usfile, usbfile, false);
  527.  
  528.   unlink(usfile);
  529.  
  530.   ufl  = open(usfile,  O_CREAT  | O_RDWR | O_BINARY, pmode);
  531.   uflb = open(usbfile, O_RDONLY | O_BINARY);
  532.  
  533.   incnt = ufhs->count;
  534.   inuhdr();
  535.  
  536.   inrec = 1;
  537.   while(incnt)
  538.   {
  539.     for (rp = tmp->scr; (rp < lp) and incnt;)
  540.     {
  541.       incnt--;
  542.       read_rec(uflb, inrec++, rp);
  543.       if (!(((USER *)rp)->options & u_delete)) rp += RECSIZE;
  544.     }
  545.     for (wp = tmp->scr; wp < rp; wp += RECSIZE)
  546.       write_rec(ufl, ++ufhs->count, wp);
  547.   }
  548.  
  549.   write_rec(ufl, 0, (char *)ufhs);
  550.   close (uflb);
  551.   clnuser();
  552.   rdusers();
  553.   rduser(port->user->call, port->user);
  554. }
  555.  
  556. /*
  557.  *  If all ports are free, Issue the command for all ports to lockup.
  558.  *  wait for confirmation and then do the command.
  559.  */
  560.  
  561. setunt()
  562. {
  563.   byte pflg;
  564.   long l;
  565.  
  566.   if (!(s_flag & s_dv))
  567.   {
  568.     switch(port->opt2)
  569.     {
  570.       case 'A' :
  571.       case 'R' :
  572.       case 'M' : untmsg(); break;
  573.       case 'U' : untuser(); break;
  574.       default  : ;
  575.     }
  576.     return;
  577.   }
  578.  
  579. /*
  580.  *  If all windows are free issue the lock command
  581.  */
  582.  
  583.   getc_flag();
  584.   if (b_flag is p_window)
  585.   {
  586.     putcomd ('A', 'H');
  587.     pflg = getp_flag();
  588.     putc_flag (pflg clrbit p_window);
  589.   }
  590.   else
  591.   {
  592.     outstr("Other windows BUSY\n");
  593.     return;
  594.   }
  595.  
  596. /*
  597.  *  Wait for windows to confirm the lock by looking for a
  598.  *  cleared c_flag. Do the command if cleared, otherwise return.
  599.  */
  600.  
  601.   settmr( &l, 20);
  602.   while (true)
  603.   {
  604.     if (!(chktmr(l)))
  605.     {
  606.       putc_flag(0); break;
  607.     }
  608.     getc_flag();
  609.     if (c_flag  is 0)
  610.     {
  611.       switch(port->opt2)
  612.         {
  613.           case 'A' :
  614.           case 'R' :
  615.           case 'M' : untmsg(); break;
  616.           case 'U' : untuser(); break;
  617.           default  : ;
  618.         }
  619.       break;
  620.     }
  621.     switchw();
  622.   }
  623.   putcomd('\0','\0');
  624. }
  625.