// 18.Dez  1996 - Loco@Morgengrauen
// 8. Feb  1995 - Jof@MorgenGrauen
// 5. Juli 1992 - Jof@MorgenGrauen
// 6. Juli 1992 - Jof@MorgenGrauen
// Clear-Groups-Mechanismus eingebaut. Die 2 Konstanten TIME_TO_CLEAR und
// MIN_TOUCHED muessen def. sein. Alle TIME_TO_CLEAR Sekunden werden die
// Newsgroups, die seit dem letzten Clear seltener als MIN_TOUCHED Sekunden
// beruehrt wurden, aus dem Cache genommen

// 1. Februar 1995 - Jof@MorgenGrauen
// Rewrite (Mappings benutzen, Accessinfos im Speicher halten)


// Datenstrukturen:

// Newsgroups:  grouplist ist ein Mapping mit einem Eintrag pro Newsgroup.
//              Die Keys sind die Gruppennamen, Daten:
//              0 Zeit des letzen Artikels
//              1 Besitzer der Gruppe
//              2 Savefille-Name
//              3 Expire-Zeit
//              4 Array mit Loesch-Berechtigten
//              5 Array mit Scheib-Berechtigten
//              6 Array mit Leseberechtigten
//              7 Mindest-Level, um Artikel zu loeschen
//              8 Mindest-Level, um Artikel zu posten
//              9 Mindest-Level, um Artikel zu lesen
//             10 Max. Anzahl Nachrichten in der Gruppe

// Die Nachrichten selber stehen in einem Array.

// Eine nachricht ist ein Array mit den folgenden Elementen:
// 0         (*) string writer;
// 1         (*) string id;    Mudname+":"+time()+":"+group zur Zeit
// 2         (*) string time;
// 3             string title;
// 4             string message;

// Die mit (*) gekennzeichneten Eintraege setzt der Daemon selber

// Funktionen:
//    Returnvalues:  0 = Parameter error
//                   1 = Ok.
//                  -1 = no permission
//                  -2 = no such group/group already existing
//
//    Diese Returnvalues stehen fuer alle Funktionen

//  AddGroup(groupname, owner, savefile);
//   Funktion klar, kann nur von Erzmagiern aufgerufen werden
//    -3 = no owner, -4 = savefile already in use
//
//  RemoveGroup(groupname);
//   Ebenfalls nur fuer Erzmagier
//
//  SetGroup(groupname, dlevel, wlevel, rlevel, maxmessages, expire);
//   Erzmagier und der Groupowner koennen die nutzen. Legt Level, ab dem je-
//   mand aus der Gruppe loeschen kann (dlevel), in die Gruppe schreiben
//   kann (wlevel), die Gruppe lesen kann (rlevel) und die max. Anzahl Nach-
//   richten in der Gruppe fest.
//
//  AddAllowed(groupname, deleters, writers, readers);
//   Erzmagier/Owner koennen Arrays mit Namen von fuer die Gruppe loesch/
//   schreib/lese-Berechtigten fuer die Gruppe angeben.
//
//  RemoveAllowed(groupname, deleters, writers, readers);  analog
//
//  WriteNote(message); klar
//   -3 = Max number of msgs exceeded
//
//  RemoveNote(boardname, notenummer); notenummer>=0;
//   -3 = No such note
//
//  GetNotes(boardname); gibt einen Array mit den Notes zurueck.
//
//  AskAllowedWrite(); return wie bei WriteNote, stellt fest, ob ein Player
//  eine Note aufhaengen darf oder nicht
//
//  GetNewsTime([boardname]); gibt zurueck, wann am entsprechenden Brett zum
//  letzten Mal eine Note befestigt wurde. Falls kein boardname angegeben
//  wird, liefert GetNewsTime() den Zeitpunkt, zu dem ueberhaupt eine neue
//  Note aufgehaengt wurde.
//
#pragma strict_types
#pragma no_clone
#pragma no_shadow
#pragma no_inherit
#pragma verbose_errors
#pragma combine_strings
//#pragma pedantic
//#pragma range_check
#pragma warn_deprecated

#include "/secure/wizlevels.h"
#include <defines.h>
#include <config.h>
#include <news.h>

#define WTIME 0

private int security( string name );

mixed saveload; // Diese Variable ist als einzige nicht nosave ist und dient
                 // Uebertragen von Daten in/aus savefiles

nosave mapping grouplist; // Groups und ihre save-Files, zudem LastTime
nosave int lasttime; // Um zu vermeiden, dass 2 Notes identische Uhrzeit==id
                     // haben, wird die jeweils letzte Zeit gespeichert.

nosave mapping cache = ([]); // cache fuer die Gruppeninhalte

void create() {
  seteuid(getuid(this_object()));
  if (!restore_object(NEWSPATH+"GroupList"))
    grouplist=m_allocate(0,G_MESSAGES);
  else
    grouplist=saveload;
  // ersten reset sobald wie moeglich. ;-)
  set_next_reset(1);
}

int AddGroup(string name, string owner)
{
  mixed *group;
  string savefile, *savefilea;
  int i;

  if (!name || !owner) return 0;
  
  if (!ARCH_SECURITY || process_call()) return -1; // Darf nicht

  if (member(grouplist, name)) return -2; // Gibt es schon

  if (!({int})master()->find_userinfo(owner)) return -3;

  savefilea = old_explode(name,".");
  savefile = implode(savefilea,"/");
  if (file_size(NEWSPATH+savefile+".o")>=0) return -4;

  // Notwendige Directories anlegen
  for (i = 0; i < sizeof(savefilea)-1; i++) {
    mkdir(NEWSPATH+implode(savefilea[0..i],"/"));
  }

  group=({});
  grouplist+=([name:0;owner;savefile;-1;({});({});({});20;0;0;80]);
  save_group_list();
  save_group(name,group);
  return 1;
}

int RemoveGroup(string name)
{
  int num;

  if (!name) return 0;

  if (!security(name) || process_call()) return -1; // Darf nicht

  if (!mappingp(grouplist) || !member(grouplist,name))
    return -2; // -2 no such group

  catch(rm(NEWSPATH+grouplist[name,G_SAVEFILE]+".o");publish);
  m_delete(grouplist,name);

  save_group_list();

  return 1;
}

int SetGroup(string name,int dlevel,int        wlevel,int rlevel,int maxmessages,int expire)
{
  mixed *group;
  
  if (!member(grouplist,name)) return -2;
  if (grouplist[name,G_OWNER]!=user_euid() &&
      (!security(name) || process_call())) return -1;
  
  grouplist[name,G_DLEVEL]=dlevel;
  grouplist[name,G_WLEVEL]=wlevel;
  grouplist[name,G_RLEVEL]=rlevel;
  grouplist[name,G_MAX_MSG]=maxmessages;
  grouplist[name,G_EXPIRE]=expire;
  
  save_group_list();
  return 1;
}

int AddAllowed(string name,mixed deleters,mixed writers,mixed readers)
{
  mixed *group;

  if (!member(grouplist,name)) return -2;

  if ( grouplist[name,G_OWNER]!=user_euid() &&
       (!security(name) || process_call()) && user_euid() != ROOTID )
      return -1;

  if (stringp(deleters)) deleters=({deleters});
  if (stringp(writers)) writers=({writers});
  if (stringp(readers)) readers=({readers});

  if (!deleters) deleters=({});
  if (!writers) writers=({});
  if (!readers) readers=({});

  grouplist[name,G_DELETERS]+=deleters;
  grouplist[name,G_WRITERS]+=writers;
  grouplist[name,G_READERS]+=readers;
        
  save_group_list();
  return 1;
}

int RemoveAllowed(string name,mixed deleters,mixed writers,mixed readers)
{
  mixed *group;

  if (!member(grouplist,name)) return -2;

  if (grouplist[name,G_OWNER]!=user_euid() &&
      (!security(name) || process_call()) && user_euid() != ROOTID )
      return -1;

  if (stringp(deleters)) deleters=({deleters});
  if (stringp(writers)) writers=({writers});
  if (stringp(readers)) readers=({readers});

  if (!deleters) deleters=({});
  if (!writers) writers=({});
  if (!readers) readers=({});

  grouplist[name,G_DELETERS]-=deleters;
  grouplist[name,G_WRITERS]-=writers;
  grouplist[name,G_READERS]-=readers;

  save_group_list();
  return 1;
}

static string user_euid()
{
  if (previous_object()) {
     if (geteuid(previous_object())==ROOTID)       return ROOTID;
     if (geteuid(previous_object())=="p.daemon")   return "p.daemon";
     if (load_name(previous_object())=="/obj/mpa") return geteuid(RPL);
  }
  return secure_euid();
}

#define F_DELETE    0
#define F_READ      1
#define F_WRITE     2
#define F_ADMIN     3
#define F_KEEPNAME  4

private int security( string name )
{
    if ( grouplist[name,G_DLEVEL] >= ARCH_LVL
         || grouplist[name,G_WLEVEL] >= ARCH_LVL
         || grouplist[name,G_RLEVEL] >= ARCH_LVL )
        return ARCH_SECURITY;
    else
        return ELDER_SECURITY;
}

static int allowed(string name, int mode)
{
  string euid;
  mixed g_level, g_mode;
  
  if (process_call()) return 0;

  euid=user_euid();

  if (euid==ROOTID) return 1;

  switch(mode) {
    case F_KEEPNAME: return (euid=="p.daemon");
    case F_WRITE:    if (euid=="p.daemon") return 1;
                     g_level=G_WLEVEL; g_mode=G_WRITERS;  break;
    case F_ADMIN:    if (!(security(name)||grouplist[name,G_OWNER]==euid)) 
                             return 0;
                     g_level=G_DLEVEL; g_mode=G_DELETERS; break;
    case F_DELETE:   if (euid=="p.daemon") return 1;
                     g_level=G_DLEVEL; g_mode=G_DELETERS; break;
    case F_READ:     g_level=G_RLEVEL; g_mode=G_READERS;  break;
    default:         return 0;
  }

  if (grouplist[name,G_OWNER] != euid && !ARCH_SECURITY &&
      grouplist[name,g_level] > query_wiz_level(euid) &&
      member(grouplist[name, g_mode], euid)==-1)
    return 0; // No such group for the requestor :)
  return 1;
}

int WriteNote(mixed message,mixed keepname)
{
  mixed group;
  int uidok,tmp;
  string name;

  if (!pointerp(message) || sizeof(message)!=6) return 0;

  if (!pointerp(group=load_group(name=message[M_BOARD]))) return -2;

  if (!allowed(name, F_WRITE)) return -1;

  if (sizeof(group)>=grouplist[name,G_MAX_MSG]) return -3;

  if (!keepname || !allowed(name, F_KEEPNAME))
     message[M_WRITER]=capitalize(geteuid(this_interactive()||previous_object()));

  if (lasttime>=time()) lasttime++;
    else lasttime=time();
  message[M_TIME]=lasttime;
  message[M_ID]=MUDNAME+":"+lasttime;
  group+=({message});
  grouplist[name,WTIME]=lasttime;
  save_group(name,group);
  save_group_list();
  return 1;
}

int RemoveNote(string name, int note)
{
  int num;
  mixed group;

  if ((note<0) && (name=="dwnews"))
  {
    group=({});
    grouplist[name,WTIME]=0;
    save_group(name,group);
    save_group_list();
    return 1;
  }

  if (note<0) return 0;

  if (!pointerp(group=load_group(name))) return -2;

  int count=sizeof(group);
  if (count<=note)
    return -3;

  if (!allowed(name, F_DELETE) &&
      lower_case(group[note][M_WRITER])!=user_euid()) return -1;

  if (count==1)
    group=({});
  else if (!note)
    group = group[1..];
  else if (note == count-1)
    group = group[0..<2];
  else
    group=group[0..note-1]+group[note+1..];
  
  if (sizeof(group))
    grouplist[name,WTIME]=group[<1][M_TIME];
  else
    grouplist[name,WTIME]=0;
  save_group(name,group);
  save_group_list();
  return 1;
}

mixed GetNotes(string name)
{
  mixed group;
  
  if (!pointerp(group=load_group(name))) return -2;
  if (!allowed(name, F_READ)) return -2;
  return(deep_copy(group)); // COPY it
}

static void dump_file(string filename,mixed news)
{
  int i;
  
  for (i=0;i<sizeof(news);i++)
    write_file(filename,news[i][M_TITLE]+" ("+news[i][M_WRITER]+", "+
               dtime(news[i][M_TIME])[5..26]+"):\n"+
               news[i][M_MESSAGE]+"\n-----------------------------------------------------------------------------\n\n\n\n");
}

protected varargs void expire(string grp,int etime)
// etime ist anfangs in Tagen und bezeichnet das max. Alter, was Artikel in
// der Gruppe haben duerfen.
{
  mixed group;

  if (!pointerp(group=load_group(grp))) return;
  if (etime)
  {
    if (etime>0)
      etime=etime*60*60*24;
  }
  else
    etime=grouplist[grp,G_EXPIRE]; 
  if (etime<=0)
    return;

  int to_expire=time()-etime;
  int size=sizeof(group);
  if (!size) return;

  int first_to_keep = size;  // ja, ist noch eins zu hoch
  // solange runterlaufen bis man ein element findet, welches geloescht werden
  // soll. first_to_keep bleibt dann eins hoeher als das.
  while ( first_to_keep && group[first_to_keep-1][M_TIME]>to_expire)
    --first_to_keep;
  // first_to_keep kann jetzt auf eins hinter dem letzten Element zeigen (==
  // size). Das wird unten beruecksichtigt.

  if (!first_to_keep) // alle behalten?
    return;
  // Zu loeschende Artikel wegschreiben.
  dump_file(NEWSPATH"OLD."+grp,group[0..first_to_keep-1]);
  // dann loeschen
  if (first_to_keep == size) // alle wegwerfen?
    group=({});
  else
    group=group[first_to_keep..size-1];
  
  save_group(grp,group);
}

void dump_group(string grp)
{
  int to_expire,size,last;
  mixed group;

  if (!ARCH_SECURITY || process_call()) return;
  if (!pointerp(group=load_group(grp))) return;
  size=sizeof(group);
  last=size;
  if (!last) return;
  dump_file(NEWSPATH"DUMP."+grp,group[0..last-1]);
}

protected void expire_all(string *keys) {
  // neuen call_out fuer den Rest setzen
  if (sizeof(keys) > 1)
    call_out(#'expire_all,15,keys[1..]);
  // und erste Gruppe expiren
  expire(keys[0]);
}

void reset() {
  // naechstes Expire und damit Reset in einem tag
  set_next_reset(86400);
  // alte call_outs ggf. entfernen.
  while(remove_call_out(#'expire_all)>=0);
  // gruppenliste holen und callout auf expire_all starten
  if (sizeof(grouplist)) {
    call_out(#'expire_all,10,m_indices(grouplist));
  }
}

static void save_group(string grp,mixed group)
{
  saveload=group; // Do NOT save the accessed-Info
  cache[grp] = group;
  save_object(NEWSPATH+grouplist[grp,G_SAVEFILE]);
  saveload=0;
}

static void save_group_list()
{
  saveload=grouplist;
  save_object(NEWSPATH+"GroupList");
  saveload=0;
}

static mixed load_group(string name)
{
  int num;
  mixed *ret;

  if(!member(grouplist,name)) return -1;

  if (member(cache, name)) {
    ret = cache[name];
  }
  else {
    restore_object(NEWSPATH+grouplist[name,G_SAVEFILE]);
    if (!pointerp(saveload))
      saveload=({});
    ret=saveload;
    cache[name] = saveload;
    saveload=0;
  }
  return ret;
}

mixed GetGroups()
{
  mixed *returnlist;
  int i,group,slevel;
  string seuid;

  returnlist=sort_array(m_indices(grouplist),#'>); //');
  if (ARCH_SECURITY && !process_call())
    return returnlist;

  seuid = user_euid();
  slevel = secure_level();

  for (i=sizeof(returnlist)-1;i>=0;i--)
    if (!(grouplist[returnlist[i],G_RLEVEL]<=slevel ||
          grouplist[returnlist[i],G_OWNER]==seuid ||
          member(grouplist[returnlist[i],G_READERS], seuid)!=-1))
      returnlist=returnlist[0..i-1]+returnlist[i+1..];
  return returnlist;
}

int AskAllowedWrite(string n)
{
  mixed group;

  if (!member(grouplist,n)) return -2;
  if (!pointerp(group=load_group(n))) return -2;

  if (grouplist[n,G_OWNER] != user_euid() &&
      !ARCH_SECURITY &&
      grouplist[n,G_WLEVEL]>secure_level() &&
      member(grouplist[n,G_WRITERS],user_euid())==-1)
    return -1;

  if (sizeof(group)>=grouplist[n,G_MAX_MSG]) return -3;
  return 1;
}

// Wichtig ...

int query_prevent_shadow()
{
  return 1;
}

mixed GetNewsTime(string boardname)

{
  int i, ltime, j;
  mixed *keys;

  if (!boardname)
  {
    ltime=-1;
    for (i=sizeof(keys=m_indices(grouplist))-1;i>=0;i--)
      if (ltime<(j=grouplist[keys[i],WTIME])) ltime=j;
    return ltime;
  }
  if (!member(grouplist,boardname)) return -1;
  return grouplist[boardname,WTIME];
}

mixed* GetGroup(string name)
{
  if (process_call()) return 0;
  if (extern_call() && !allowed(name, F_ADMIN)) return 0;
#define gl(x) grouplist[name,x]
  return ({name,gl(1),gl(2),gl(3),gl(4),gl(5),gl(6),gl(7),gl(8),gl(9),gl(10),load_group(name)});
}
