Пример #1
0
bool iscan1(int si)
// Initializes use of a sub value (subboards[], not usub[]).  If quick, then
// don't worry about anything detailed, just grab qscan info.
{
  postrec p;

  // make sure we have cache space
  if (!cache) {
    cache = static_cast<postrec *>(malloc(MAX_TO_CACHE * sizeof(postrec)));
    if (!cache) {
      return false;
    }
  }
  // forget it if an invalid sub #
  if (si < 0 || si >= initinfo.num_subs) {
    return false;
  }

  // see if a sub has changed
  if (subchg) {
    SetCurrentReadMessageArea(-1);
  }

  // if already have this one set, nothing more to do
  if (si == GetCurrentReadMessageArea()) {
    return true;
  }
  // sub cache no longer valid
  believe_cache = false;

  // set sub filename
  snprintf(subdat_fn, sizeof(subdat_fn), "%s%s.sub", syscfg.datadir, subboards[si].filename);

  // open file, and create it if necessary
  if (!WFile::Exists(subdat_fn)) {
    if (!open_sub(true)) {
      return false;
    }
    p.owneruser = 0;
    fileSub.Write(&p, sizeof(postrec));
  } else if (!open_sub(false)) {
    return false;
  }

  // set sub
  SetCurrentReadMessageArea(si);
  subchg = 0;
  last_msgnum = 0;

  // read in first rec, specifying # posts
  fileSub.Seek(0L, WFile::seekBegin);
  fileSub.Read(&p, sizeof(postrec));
  SetNumMessagesInCurrentMessageArea(p.owneruser);

  // close file
  close_sub();

  // iscanned correctly
  return true;
}
Пример #2
0
void add_post(postrec *pp)
{
    postrec p;
    int close_file=0;

  /* open the sub, if necessary  */
    
    if (sub_f <= 0)
    {
        open_sub(1);
        close_file=1;
    }

    if (sub_f>=0)
    {
        /* get updated info */
        read_status();
        sh_lseek(sub_f, 0L, SEEK_SET);
        sh_read(sub_f, &p, sizeof(postrec));

        /* one more post */
        p.owneruser++;
        nummsgs=p.owneruser;
        sh_lseek(sub_f, 0L, SEEK_SET);
        sh_write(sub_f, &p, sizeof(postrec));

        /* add the new post */
        sh_lseek(sub_f, ((long)nummsgs)*sizeof(postrec), SEEK_SET);
        sh_write(sub_f, pp, sizeof(postrec));

        /* we've modified the sub */
        believe_cache=0;
        subchg=0;
        sub_dates[curlsub]=pp->qscan;
    }

    if (close_file)
        close_sub();
}
Пример #3
0
void post(void)
{
  messagerec m;
  postrec p;
  char s[121];
  int i,dm,a,flag;
  time_t time1, time2;

    flag=0;

    m.storage_type=subboards[curlsub].storage_type;
    a=0;

    time1=time(NULL);

//  write_inst(INST_LOC_POST,curlsub,INST_FLAGS_NONE);

//  inmsg(&m,p.title,&a,1,(subboards[curlsub].filename),ALLOW_FULLSCREEN,
//    subboards[curlsub].name, (subboards[curlsub].anony&anony_no_tag)?1:0);
    savefile(buffer,length,&m,(subboards[curlsub].filename));
    if (m.stored_as!=0xffffffff)
    {
        p.anony=a;
        p.msg=m;
        p.ownersys=0;
        p.owneruser=usernum;
        lock_status();
        p.qscan=status.qscanptr++;
        save_status();
        time((long *)(&p.daten));
        p.status=0;

        open_sub(1);

        if ((xsubs[curlsub].num_nets) &&
          (subboards[curlsub].anony & anony_val_net) && (!lcs() || irt[0])) {
          p.status |= status_pending_net;
          dm=1;
          for (i=nummsgs; (i>=1) && (i>(nummsgs-28)); i--) {
            if (get_post(i)->status & status_pending_net) {
              dm=0;
              break;
        }
      }
      if (dm) {
        sprintf(s,get_stringx(1,37),subboards[curlsub].name);
        ssm(1,0,s);
      }
    }


    if (nummsgs>=subboards[curlsub].maxmsgs) {
      i=1;
      dm=0;
      while ((dm==0) && (i<=nummsgs)) {
        if ((get_post(i)->status & status_no_delete)==0)
          dm=i;
        ++i;
      }
      if (dm==0)
        dm=1;
      delete(dm);
    }

    add_post(&p);
    lock_status();
    ++status.msgposttoday;
    ++status.localposts;


    save_status();
    close_sub();

    if (xsubs[curlsub].num_nets) {
      if (!(p.status & status_pending_net))
        send_net_post(&p, subboards[curlsub].filename, curlsub);
    }
  }
}
Пример #4
0
void valscan() {
  // Must be local cosysop or better
  if (!lcs()) {
    return;
  }

  int ac = 0;
  int os = GetSession()->GetCurrentMessageArea();

  if (uconfsub[1].confnum != -1 && okconf(GetSession()->GetCurrentUser())) {
    ac = 1;
    tmp_disable_conf(true);
  }
  bool done = false;
  for (int sn = 0; sn < GetSession()->num_subs && !hangup && !done; sn++) {
    if (!iscan(sn)) {
      continue;
    }
    if (GetSession()->GetCurrentReadMessageArea() < 0) {
      return;
    }

    uint32_t sq = qsc_p[sn];

    // Must be sub with validation "on"
    if (!(xsubs[GetSession()->GetCurrentReadMessageArea()].num_nets)
        || !(subboards[GetSession()->GetCurrentReadMessageArea()].anony & anony_val_net)) {
      continue;
    }

    GetSession()->bout.NewLine();
    GetSession()->bout.Color(2);
    GetSession()->bout.ClearEOL();
    GetSession()->bout << "{{ ValScanning " << subboards[GetSession()->GetCurrentReadMessageArea()].name << " }}\r\n";
    lines_listed = 0;
    GetSession()->bout.ClearEOL();
    if (okansi() && !newline) {
      GetSession()->bout << "\r\x1b[2A";
    }

    for (int i = 1; i <= GetSession()->GetNumMessagesInCurrentMessageArea() && !hangup && !done; i++) {    // was i = 0
      if (get_post(i)->status & status_pending_net) {
        CheckForHangup();
        GetSession()->localIO()->tleft(true);
        if (i > 0 && i <= GetSession()->GetNumMessagesInCurrentMessageArea()) {
          bool next;
          int val;
          read_message(i, &next, &val);
          GetSession()->bout << "|#4[|#4Subboard: " << subboards[GetSession()->GetCurrentReadMessageArea()].name << "|#1]\r\n";
          GetSession()->bout <<  "|#1D|#9)elete, |#1R|#9)eread |#1V|#9)alidate, |#1M|#9)ark Validated, |#1Q|#9)uit: |#2";
          char ch = onek("QDVMR");
          switch (ch) {
          case 'Q':
            done = true;
            break;
          case 'R':
            i--;
            continue;
          case 'V': {
            open_sub(true);
            resynch(&i, nullptr);
            postrec *p1 = get_post(i);
            p1->status &= ~status_pending_net;
            write_post(i, p1);
            close_sub();
            send_net_post(p1, subboards[GetSession()->GetCurrentReadMessageArea()].filename,
                          GetSession()->GetCurrentReadMessageArea());
            GetSession()->bout.NewLine();
            GetSession()->bout << "|#7Message sent.\r\n\n";
          }
          break;
          case 'M':
            if (lcs() && i > 0 && i <= GetSession()->GetNumMessagesInCurrentMessageArea() &&
                subboards[GetSession()->GetCurrentReadMessageArea()].anony & anony_val_net &&
                xsubs[GetSession()->GetCurrentReadMessageArea()].num_nets) {
              open_sub(true);
              resynch(&i, nullptr);
              postrec *p1 = get_post(i);
              p1->status &= ~status_pending_net;
              write_post(i, p1);
              close_sub();
              GetSession()->bout.NewLine();
              GetSession()->bout << "|#9Not set for net pending now.\r\n\n";
            }
            break;
          case 'D':
            if (lcs()) {
              if (i > 0) {
                open_sub(true);
                resynch(&i, nullptr);
                postrec p2 = *get_post(i);
                delete_message(i);
                close_sub();
                if (p2.ownersys == 0) {
                  WUser tu;
                  GetApplication()->GetUserManager()->ReadUser(&tu, p2.owneruser);
                  if (!tu.IsUserDeleted()) {
                    if (static_cast<unsigned long>(date_to_daten(tu.GetFirstOn())) < p2.daten) {
                      GetSession()->bout.NewLine();
                      GetSession()->bout << "|#2Remove how many posts credit? ";
                      char szNumCredits[ 11 ];
                      input(szNumCredits, 3, true);
                      int nNumPostCredits = 1;
                      if (szNumCredits[0]) {
                        nNumPostCredits = atoi(szNumCredits);
                      }
                      nNumPostCredits = std::min<int>(tu.GetNumMessagesPosted(), nNumPostCredits);
                      if (nNumPostCredits) {
                        tu.SetNumMessagesPosted(tu.GetNumMessagesPosted() - static_cast<unsigned short>(nNumPostCredits));
                      }
                      GetSession()->bout.NewLine();
                      GetSession()->bout << "|#3Post credit removed = " << nNumPostCredits << wwiv::endl;
                      tu.SetNumDeletedPosts(tu.GetNumDeletedPosts() + 1);
                      GetApplication()->GetUserManager()->WriteUser(&tu, p2.owneruser);
                      GetApplication()->UpdateTopScreen();
                    }
                  }
                }
                resynch(&i, &p2);
              }
            }
            break;
          }
        }
      }
    }
    qsc_p[sn] = sq;
  }

  if (ac) {
    tmp_disable_conf(false);
  }

  GetSession()->SetCurrentMessageArea(os);
  GetSession()->bout.NewLine(2);
}
Пример #5
0
postrec *get_post(unsigned short mn)
/*
 * Returns info for a post.  Maintains a cache.  Does not correct anything
 * if the sub has changed.
 */
{
  postrec p;
  int close_file;

  if (mn==0)
    return(NULL);

  if (subchg==1) {
    /* sub has changed (detected in read_status); invalidate cache */
    believe_cache=0;

    /* kludge: subch==2 leaves subch indicating change, but the '2' value */
    /* indicates, to this routine, that it has been handled at this level */
    subchg=2;
  }

  /* see if we need new cache info */
  if ((!believe_cache) ||
      (mn<cache_start) ||
      (mn>=(cache_start+MAX_TO_CACHE))) {

    if (sub_f < 0) {
      /* open the sub data file, if necessary */
      if (open_sub(0)<0)
        return(NULL);

      close_file = 1;
    } else {
      close_file = 0;
    }

    /* re-read # msgs, if needed */
    if (subchg==2) {
      sh_lseek(sub_f, 0L, SEEK_SET);
      sh_read(sub_f, &p, sizeof(postrec));
      nummsgs=p.owneruser;

      /* another kludge: subch==3 indicates we have re-read # msgs also */
      /* only used so we don't do this every time through */
      subchg=3;

      /* adjust msgnum, if it is no longer valid */
      if (mn>nummsgs)
        mn=nummsgs;
    }

    /* select new starting point of cache */
    if (mn >= last_msgnum) {
      /* going forward */

      if (nummsgs<=MAX_TO_CACHE)
        cache_start=1;

      else if (mn>(nummsgs-MAX_TO_CACHE))
        cache_start=nummsgs-MAX_TO_CACHE+1;

      else
        cache_start = mn;

    } else {
      /* going backward */
      if (mn>MAX_TO_CACHE)
        cache_start = mn-MAX_TO_CACHE+1;
      else
        cache_start = 1;
    }

    if (cache_start<1)
      cache_start=1;

    /* read in some sub info */
    sh_lseek(sub_f, ((long) cache_start)*sizeof(postrec), SEEK_SET);
    sh_read(sub_f, cache, MAX_TO_CACHE*sizeof(postrec));

    /* now, close the file, if necessary */
    if (close_file) {
      close_sub();
    }

    /* cache is now valid */
    believe_cache = 1;
  }

  /* error if msg # invalid */
  if ((mn<1) || (mn>nummsgs))
    return(NULL);

  last_msgnum=mn;

  return(cache+(mn-cache_start));
}
Пример #6
0
int iscan1(int si, int quick)
/*
 * Initializes use of a sub value (subboards[], not usub[]).  If quick, then
 * don't worry about anything detailed, just grab qscan info.
 */
{
  postrec p;

  /* make sure we have cache space */
  if (!cache) {
    cache=malloca(MAX_TO_CACHE*sizeof(postrec));
    if (!cache)
      return(0);
  }
  /* forget it if an invalid sub # */
  if ((si<0) || (si>=num_subs))
    return(0);

  /* skip this stuff if being called from the WFC cache code */
  if (!quick) {

    /* go to correct net # */
    if (xsubs[si].num_nets)
      set_net_num(xsubs[si].nets[0].net_num);
    else
      set_net_num(0);

    /* see if a sub has changed */
    read_status();
    /* if already have this one set, nothing more to do */
    if (si==currsub)
      return(1);
  }
  currsub=si;

  /* sub cache no longer valid */
  believe_cache=0;

  /* set sub filename */
  sprintf(subdat_fn,"%s%s.SUB",syscfg.datadir,subboards[si].filename);
  /* open file, and create it if necessary */
  if (open_sub(0)<0) {
    if (open_sub(1)<0)
      return(0);
    p.owneruser=0;
    sh_write(sub_f,(void *) &p,sizeof(postrec));
  }

  /* set sub */
  curlsub=si;
  subchg=0;
  last_msgnum=0;

  /* read in first rec, specifying # posts */
  sh_lseek(sub_f,0L,SEEK_SET);
  sh_read(sub_f,&p, sizeof(postrec));
  nummsgs=p.owneruser;

  /* read in sub date, if don't already know it */
  if (sub_dates[si]==0) {
    if (nummsgs) {
      sh_lseek(sub_f, ((long) nummsgs)*sizeof(postrec), SEEK_SET);
      sh_read(sub_f, &p, sizeof(postrec));
      sub_dates[si]=p.qscan;
    } else {
      sub_dates[si]=1;
    }
  }

  /* close file */
  close_sub();

  /* iscanned correctly */
  return(1);
}
Пример #7
0
void deletemsg(int mn)
{
  postrec *p1, p;
  int close_file=0;
  unsigned int nb;
  char *buf;
//  char scratch[181];
  long len, l, cp;

  /* open file, if needed */
  if (sub_f <= 0) {
    open_sub(1);
    close_file=1;
  }

  /* see if anything changed */
  read_status();

  if (sub_f >= 0) {
    if ((mn>0) && (mn<=nummsgs)) {
      buf=(char *)malloca(BUFSIZE);
      if (buf) {
        p1=get_post(mn);
        remove_link(&(p1->msg),(subboards[curlsub].filename));

        cp=((long)mn+1)*sizeof(postrec);
        len=((long)(nummsgs+1))*sizeof(postrec);

        do {
          l=len-cp;
          if (l<BUFSIZE)
            nb=(int)l;
          else
            nb=BUFSIZE;
          if (nb) {
            sh_lseek(sub_f, cp, SEEK_SET);
            sh_read(sub_f, buf, nb);
            sh_lseek(sub_f, cp-sizeof(postrec), SEEK_SET);
            sh_write(sub_f, buf, nb);
            cp += nb;
          }
        } while (nb==BUFSIZE);

        /* update # msgs */
        sh_lseek(sub_f, 0L, SEEK_SET);
        sh_read(sub_f, &p, sizeof(postrec));
        p.owneruser--;
        nummsgs=p.owneruser;
        sh_lseek(sub_f, 0L, SEEK_SET);
        sh_write(sub_f, &p, sizeof(postrec));

        /* cache is now invalid */
        believe_cache = 0;

        bbsfree(buf);
      }
    }
  }

  /* close file, if needed */
  if (close_file)
    close_sub();

}
Пример #8
0
 /*! Create Sub-File/Directory to \c this with local name \p pathL.
  * \return 0 on success, -1 on error and see \c errno. */
 int create_sub(const csc& pathL, mode_t mode = PDIR_SUB_MODE) { return open_sub(pathL, O_CREAT|O_WRONLY|O_TRUNC, mode); }
Пример #9
0
postrec *get_post(int mn)
// Returns info for a post.  Maintains a cache.  Does not correct anything
// if the sub has changed.
{
  postrec p;
  bool bCloseSubFile = false;

  if (mn == 0) {
    return nullptr;
  }

  if (subchg == 1) {
    // sub has changed (detected in GetApplication()->GetStatusManager()->Read); invalidate cache
    believe_cache = false;

    // kludge: subch==2 leaves subch indicating change, but the '2' value
    // indicates, to this routine, that it has been handled at this level
    subchg = 2;
  }
  // see if we need new cache info
  if (!believe_cache ||
      mn < cache_start ||
      mn >= (cache_start + MAX_TO_CACHE)) {
    if (!fileSub.IsOpen()) {
      // open the sub data file, if necessary
      if (!open_sub(false)) {
        return nullptr;
      }
      bCloseSubFile = true;
    }

    // re-read # msgs, if needed
    if (subchg == 2) {
      fileSub.Seek(0L, WFile::seekBegin);
      fileSub.Read(&p, sizeof(postrec));
      SetNumMessagesInCurrentMessageArea(p.owneruser);

      // another kludge: subch==3 indicates we have re-read # msgs also
      // only used so we don't do this every time through
      subchg = 3;

      // adjust msgnum, if it is no longer valid
      if (mn > GetNumMessagesInCurrentMessageArea()) {
        mn = GetNumMessagesInCurrentMessageArea();
      }
    }
    // select new starting point of cache
    if (mn >= last_msgnum) {
      // going forward
      if (GetNumMessagesInCurrentMessageArea() <= MAX_TO_CACHE) {
        cache_start = 1;
      } else if (mn > (GetNumMessagesInCurrentMessageArea() - MAX_TO_CACHE)) {
        cache_start = GetNumMessagesInCurrentMessageArea() - MAX_TO_CACHE + 1;
      } else {
        cache_start = mn;
      }
    } else {
      // going backward
      if (mn > MAX_TO_CACHE) {
        cache_start = mn - MAX_TO_CACHE + 1;
      } else {
        cache_start = 1;
      }
    }

    if (cache_start < 1) {
      cache_start = 1;
    }

    // read in some sub info
    fileSub.Seek(cache_start * sizeof(postrec), WFile::seekBegin);
    fileSub.Read(cache, MAX_TO_CACHE * sizeof(postrec));

    // now, close the file, if necessary
    if (bCloseSubFile) {
      close_sub();
    }
    // cache is now valid
    believe_cache = true;
  }
  // error if msg # invalid
  if (mn < 1 || mn > GetNumMessagesInCurrentMessageArea()) {
    return nullptr;
  }
  last_msgnum = mn;
  return (cache + (mn - cache_start));
}