// 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)
{
  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)
{
  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)
{
  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)
{
  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;
  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)
{
  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 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)
{
  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,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)});
}

public varargs void AllGroups(int details) {
  if (!ARCH_SECURITY || process_call()) return; // Darf nicht

  string* gnames = sort_array(m_indices(grouplist), #'>);

  printf("%-25s %-11s %12s %3s %3s %3s %3s\n",
         "Name","Owner","Expire","Max","Rea","Wri","Del");
  printf("-"*78 + "\n");
  foreach (string g : gnames)
  {
    printf("%-25s %-11s %12s %3d %3d %3d %3d\n",
      g, grouplist[g,1], time2string("%dd %02h:%02m", grouplist[g,3]),
      grouplist[g,10], grouplist[g,9], grouplist[g,8], grouplist[g,7]);
    if (details) {
      if (sizeof(grouplist[g,6])) // readers
        printf(break_string(implode(grouplist[g,6], " "), 78, "  Rea: ",
          BS_INDENT_ONCE));
      if (sizeof(grouplist[g,5])) // writers
        printf(break_string(implode(grouplist[g,5], " "), 78, "  Wri: ",
          BS_INDENT_ONCE));
      if (sizeof(grouplist[g,4])) // deleters
        printf(break_string(implode(grouplist[g,5], " "), 78, "  Del: ",
          BS_INDENT_ONCE));
    }
  }
}
