aboutsummaryrefslogtreecommitdiffstats
path: root/FICS/lists.c
diff options
context:
space:
mode:
authorMarkus Uhlin <markus@nifty-networks.net>2023-12-07 21:31:49 +0100
committerMarkus Uhlin <markus@nifty-networks.net>2023-12-07 21:31:49 +0100
commit79b59f9b30fb6a1fdf8c3efb446271f7cb00d434 (patch)
treef6ade4ccbc3af20d825edacfd12b5da8ded8d240 /FICS/lists.c
FICS 1.6.2
Diffstat (limited to 'FICS/lists.c')
-rw-r--r--FICS/lists.c470
1 files changed, 470 insertions, 0 deletions
diff --git a/FICS/lists.c b/FICS/lists.c
new file mode 100644
index 0000000..7e3748d
--- /dev/null
+++ b/FICS/lists.c
@@ -0,0 +1,470 @@
+/* lists.c
+
+ * New global lists code
+ *
+ * Part of: FICS
+ *
+ * Added by Shaney, 29 May 1995 :)
+ * sometime in Oct 1995: changed things a little (loon)
+ *
+
+*/
+
+#include "lists.h"
+#include "common.h"
+#include "multicol.h"
+#include "command.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "rmalloc.h"
+#include "talkproc.h"
+#include "gamedb.h"
+#include "stdinclude.h"
+#include "comproc.h"
+
+#include <string.h>
+
+List *firstGlobalList = NULL;
+
+PRIVATE ListTable ListArray[] =
+{{P_HEAD, "admin"},
+{P_GOD, "removedcom"},
+{P_ADMIN, "filter"},
+{P_ADMIN, "ban"},
+{P_ADMIN, "abuser"},
+{P_ADMIN, "muzzle"},
+{P_ADMIN, "cmuzzle"},
+{P_PUBLIC, "fm"},
+{P_PUBLIC, "im"},
+{P_PUBLIC, "gm"},
+{P_PUBLIC, "blind"},
+{P_PUBLIC, "teams"},
+{P_PUBLIC, "computer"},
+{P_PUBLIC, "td"},
+{P_PERSONAL, "censor"},
+{P_PERSONAL, "gnotify"},
+{P_PERSONAL, "noplay"},
+{P_PERSONAL, "notify"},
+{P_PERSONAL, "channel"},
+{0, NULL}};
+
+/* find a list. loads from disk if not in memory. */
+PRIVATE List *list_find(int p, enum ListWhich l)
+{
+ List *prev, *tempList, **starter;
+ int personal;
+ int count = 0;
+
+ personal = ListArray[l].rights == P_PERSONAL;
+ starter = personal ? &(parray[p].lists) : &firstGlobalList;
+
+ for (prev = NULL, tempList = *starter; tempList != NULL; tempList = tempList->next) {
+ if (l == tempList->which) {
+ if (prev != NULL) {
+ prev->next = tempList->next;
+ tempList->next = *starter;
+ *starter = tempList;
+ }
+ return tempList;
+ }
+ prev = tempList;
+ }
+
+ tempList = rmalloc(sizeof(List));
+ if (tempList == NULL)
+ return NULL;
+
+ if (!personal) { /* now we have to load the list */
+ FILE *fp;
+ char listmember[100];
+ char filename[MAX_FILENAME_SIZE];
+
+ /* fprintf(stderr,"SHANEDEBUG: Adding %s list\n", ListArray[l].name); */
+
+ sprintf(filename, "%s/%s", lists_dir, ListArray[l].name);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ rfree(tempList);
+ return NULL;
+ }
+ while (!feof(fp)) {
+ if (fgets(listmember, 100, fp) != NULL) {
+ listmember[strlen(listmember) - 1] = '\0';
+ tempList->member[count++] = strdup(listmember);
+ }
+ }
+ fclose(fp);
+ }
+ tempList->which = l;
+ tempList->numMembers = count;
+ tempList->next = *starter;
+ *starter = tempList;
+ return tempList;
+}
+
+/* add item to list */
+PUBLIC int list_add(int p, enum ListWhich l, char *s)
+{
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ if (gl->numMembers < MAX_GLOBAL_LIST_SIZE) {
+ gl->member[gl->numMembers] = strdup(s);
+ gl->numMembers++;
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return 1;
+ }
+}
+
+/* remove item from list */
+PUBLIC int list_sub(int p, enum ListWhich l, char *s)
+{
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ int i, found = -1;
+ for (i = 0; i < gl->numMembers; i++)
+ if (!strcasecmp(s, gl->member[i])) {
+ found = i;
+ break;
+ }
+ if (found == -1)
+ return 1;
+ rfree(gl->member[found]);
+ for (i = found; i < (gl->numMembers - 1); i++)
+ gl->member[i] = gl->member[i + 1];
+ gl->numMembers--;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/* pretty cheesy: print each member of a list, 1 per line */
+PUBLIC void list_print(FILE * fp, int p, enum ListWhich l)
+{
+ int i;
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ for (i = 0; i < gl->numMembers; i++)
+ fprintf(fp, "%s\n", gl->member[i]);
+ }
+}
+
+/* return size of a list */
+PUBLIC int list_size(int p, enum ListWhich l)
+{
+ List *gl = list_find(p, l);
+
+ if (gl)
+ return (gl->numMembers);
+ else
+ return 0;
+}
+
+/* find list by name, doesn't have to be the whole name */
+PRIVATE List *list_findpartial(int p, char *which, int gonnado)
+{
+ List *gl;
+ int i, foundit, slen;
+
+ slen = strlen(which);
+ for (i = 0, foundit = -1; ListArray[i].name != NULL; i++) {
+ if (!strncasecmp(ListArray[i].name, which, slen)) {
+ if (foundit == -1)
+ foundit = i;
+ else
+ return NULL; /* ambiguous */
+ }
+ }
+
+ if (foundit != -1) {
+ int rights = ListArray[foundit].rights;
+ int youlose = 0;
+
+ switch (rights) { /* check rights */
+ case P_HEAD:
+ if (gonnado && !player_ishead(p))
+ youlose = 1;
+ break;
+ case P_GOD:
+ if ((gonnado && (parray[p].adminLevel < ADMIN_GOD)) ||
+ (!gonnado && (parray[p].adminLevel < ADMIN_ADMIN)))
+ youlose = 1;
+ break;
+ case P_ADMIN:
+ if (parray[p].adminLevel < ADMIN_ADMIN)
+ youlose = 1;
+ break;
+ case P_PUBLIC:
+ if (gonnado && (parray[p].adminLevel < ADMIN_ADMIN))
+ youlose = 1;
+ break;
+ }
+ if (youlose) {
+ pprintf(p, "\"%s\" is not an appropriate list name or you have insufficient rights.\n", which);
+ return NULL;
+ }
+ gl = list_find(p, foundit);
+ } else {
+ pprintf(p, "\"%s\" does not match any list name.\n", which);
+ return NULL;
+ }
+ return gl;
+}
+
+/* see if something is in a list */
+PUBLIC int in_list(int p, enum ListWhich which, char *member)
+{
+ List *gl;
+ int i;
+ int filterList = (which == L_FILTER);
+
+ gl = list_find(p, which);
+ if ((gl == NULL) || (member == NULL))
+ return 0;
+ for (i = 0; i < gl->numMembers; i++) {
+ if (filterList) {
+ if (!strncasecmp(member, gl->member[i], strlen(gl->member[i])))
+ return 1;
+ } else {
+ if (!strcasecmp(member, gl->member[i]))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* add or subtract something to/from a list */
+PUBLIC int list_addsub(int p, char* list, char* who, int addsub)
+{
+ int p1, connected, loadme, personal, ch;
+ char *listname, *member;
+ List *gl;
+ char *yourthe, *addrem;
+
+ gl = list_findpartial(p, list, addsub);
+ if (!gl)
+ return COM_OK;
+
+ personal = ListArray[gl->which].rights == P_PERSONAL;
+ loadme = (gl->which != L_FILTER) && (gl->which != L_REMOVEDCOM) && (gl->which != L_CHANNEL);
+ listname = ListArray[gl->which].name;
+ yourthe = personal ? "your" : "the";
+ addrem = (addsub == 1) ? "added to" : "removed from";
+
+ if (loadme) {
+ if (!FindPlayer(p, who, &p1, &connected)) {
+ if (addsub == 1)
+ return COM_OK;
+ member = who; /* allow sub removed/renamed player */
+ loadme = 0;
+ } else
+ member = parray[p1].name;
+ } else {
+ member = who;
+ }
+
+ if (addsub == 1) { /* add to list */
+
+ if (gl->which == L_CHANNEL) {
+
+ if (sscanf (who,"%d",&ch) == 1) {
+
+ if ((!in_list(p,L_ADMIN,parray[p].name)) && (ch == 0)) {
+ pprintf(p, "Only admins may join channel 0.\n");
+ return COM_OK;
+ }
+
+ if (ch > (MAX_CHANNELS - 1)) {
+ pprintf(p,"The maximum channel number is %d.\n",MAX_CHANNELS-1);
+ return COM_OK;
+ }
+ } else {
+ pprintf (p,"Your channel to add must be a number between 0 and %d.\n",MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ }
+ if (in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is already on %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (list_add(p, gl->which, member)) {
+ pprintf(p, "Sorry, %s %s list is full.\n", yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ } else if (addsub == 2) { /* subtract from list */
+ if (!in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is not in %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ list_sub(p, gl->which, member);
+ }
+ pprintf(p, "[%s] %s %s %s list.\n", member, addrem, yourthe, listname);
+
+ if (!personal) {
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+
+ switch (gl->which) {
+ case L_MUZZLE:
+ case L_CMUZZLE:
+ case L_ABUSER:
+ case L_BAN:
+ pprintf(p, "Please leave a comment to explain why %s was %s the %s list.\n", member, addrem, listname);
+ pcommand(p, "addcomment %s %s %s list.\n", member, addrem, listname);
+ break;
+ case L_COMPUTER:
+ if (parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, member, &parray[p1].b_stats, member);
+ if (parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, member, &parray[p1].s_stats, member);
+ if (parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, member, &parray[p1].w_stats, member);
+ break;
+ case L_ADMIN:
+ if (addsub == 1) { /* adding to list */
+ parray[p1].adminLevel = 10;
+ pprintf(p, "%s has been given an admin level of 10 - change with asetadmin.\n", member);
+ } else {
+ parray[p1].adminLevel = 0;
+ }
+ break;
+ case L_FILTER:
+ pprintf(p, "Please leave a message for filter to explain why site %s was %s filter list.\n", member, addrem);
+ break;
+ case L_REMOVEDCOM:
+ pprintf(p, "Please leave a message on anews to explain why %s was %s removedcom list.\n", member, addrem);
+ break;
+ default:
+ break;
+ }
+ if (loadme && connected) {
+ pprintf_prompt(p1, "You have been %s the %s list by %s.\n", addrem, listname, parray[p].name);
+ }
+ sprintf(filename, "%s/%s", lists_dir, listname);
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "Couldn't save %s list.\n", listname);
+ } else {
+ int i;
+ for (i = 0; i < gl->numMembers; i++)
+ fprintf(fp, "%s\n", gl->member[i]);
+ fclose(fp);
+ }
+ }
+ if (loadme || (gl->which == L_ADMIN)) {
+ player_save(p1);
+ }
+ if (loadme && !connected) {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_addlist(int p, param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 1);
+}
+
+PUBLIC int com_sublist(int p,param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 2);
+}
+
+PUBLIC int com_showlist(int p, param_list param)
+{
+ List *gl;
+ int i, rights;
+
+ char *rightnames[] = {"EDIT HEAD, READ ADMINS", "EDIT GODS, READ ADMINS", "READ/WRITE ADMINS", "PUBLIC", "PERSONAL"};
+
+ if (param[0].type == 0) { /* Show all lists */
+ pprintf(p, "Lists:\n\n");
+ for (i = 0; ListArray[i].name != NULL; i++) {
+ rights = ListArray[i].rights;
+ if ((rights > P_ADMIN) || (parray[p].adminLevel >= ADMIN_ADMIN))
+ pprintf(p, "%-20s is %s\n", ListArray[i].name, rightnames[rights]);
+ }
+ } else { /* find match in index */
+ gl = list_findpartial(p, param[0].val.word, 0);
+ if (!gl) {
+ return COM_OK;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ pprintf(p, "-- %s list: %d %s --", ListArray[gl->which].name,
+ gl->numMembers,
+ ((!(strcmp(ListArray[gl->which].name,"filter"))) ? "ips" : (!(strcmp(ListArray[gl->which].name,"removedcom"))) ? "commands" : (!(strcmp(ListArray[gl->which].name,"channel"))) ? "channels" : "names"));
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->member[i]);
+ multicol_pprint(m, p, 78, 2);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int list_channels(int p,int p1)
+{
+ List *gl;
+ int i, rights;
+
+ gl = list_findpartial(p1, "channel", 0);
+ if (!gl) {
+ return 1;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ if (gl->numMembers == 0)
+ return 1;
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->member[i]);
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ }
+ return 0;
+}
+
+/* free the memory used by a list */
+PUBLIC void list_free(List * gl)
+{
+ int i;
+ List *temp;
+
+ while (gl) {
+ for (i = 0; i < gl->numMembers; i++) {
+ strfree(gl->member[i]);
+ }
+ temp = gl->next;
+ rfree(gl);
+ gl = temp;
+ }
+}
+
+PUBLIC int titled_player(int p,char* name)
+{
+ if ((in_list(p, L_FM, name)) || (in_list(p, L_IM, name)) || (in_list(p, L_GM, name))) {
+ return 1;
+ } else {
+ return 0;
+ }
+}