diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..e1791c5c6d1712aee1c214c509388a9a94c50df2 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,382 @@ +Tue Mar 5 17:13:25 1991 Per Cederqvist (ceder at lave) + + * Depend.make: Bytt -MM mot -M, eftersom vi har includefiler inom + <> som {ndrar p} sig. + +Thu Feb 14 03:39:16 1991 Linus Tolke (linus at laila) + + * include/kom-types.h: Lagt till EMPTY_CONF_NO_LIST_i och + EMPTY_CONF_NO_LIST. + +Sat Dec 15 20:46:41 1990 Per Cederqvist (ceder at laila) + + * Depend.make: Jag bytte @\{63\} mot @@@* som {r mer portabelt. + +Tue Sep 18 20:46:42 1990 Per Cederqvist (ceder at lave) + + * get_time(): nytt format. Se services.h. + +Thu Sep 13 21:32:41 1990 Per Cederqvist (ceder at lave) + + * Ny port: 4894. Jag vill kunna k|ra nya ramkomd och gamla ramkomd + p} lave samtidigt... + +Tue Aug 28 13:53:36 1990 Per Cederqvist (ceder at lave) + + * Datafilerna heter nu ramkomd-data-2 och ramkomd-backup-2. De + anv{nds av den nya servern och inneh}ller de nya formaten p} + tider och textstatusar. + + De gamla filerna ramkomd-data och ramkomd-backup finns + fortfarande kvar och anv{nds av den gamla servern. Personer som + skapas i den kommer inte att finnas i den nya servern... + +Sun Aug 26 16:40:58 1990 Per Cederqvist (ceder at lage) + + * En klient i elisp har p}b|rjats. Den ligger under + 2kom/elisp-client/. + + * [ndringar p}g}r i servern. Just nu g}r den inte att k|ra. Jag + byter externt format p} Text_stat och time_t. I forts{ttningen + blir det en struct tm som |verf|rs. + +Tue Aug 21 19:27:07 1990 Per Cederqvist (ceder at lave) + + * get_text() tar nu tv} nya parametrar som anger f|rsta och sista + tecken i texten som man h{mtar. (Normalt torde det l|na sig att + h{mta hela texten p} en g}ng. Det {r nog bara om man k|r |ver + atlantlinan som det kanske blir segt.) + +Sat Aug 11 00:31:32 1990 Per Cederqvist (ceder at lave) + + * Nya funktioner: get_membership(), get_created_texts() + och get_members(). + + * Namnbyte: query_unread() heter nu query_read_texts(). S} + sm}ningom kommer jag att skriva en annan query_unread() som + returnerar antalet ol{sta brev en person har. + + * Till slut s} lyckades jag f} allt genom kompilatorn. Det gick }t + en del tid efter alla odokumenterade omorganisationer... Nu {r + bara fr}gan hur mycket som fungerar i verkligheten... + + * kom-types.c {r flyttad till server/ resp. isc-client/. Det gick inte + att ha det i samma fil l{ngre. + +Thu Aug 9 05:20:20 1990 Thomas Bellman (bellman at laila) + + * Makefilen {nnu mer f|rb{ttrad. Make depend mycket snyggare, + anv{nder ${MAKE} i st f make direkt. + + * Makefilen i toppdirret f|rb{ttrad, likaledes ig}r. Make clean i + toppdirret g}r nu ner och g|r make clean i underdirren ocks}. + Diverse andra f|rb{ttringar ocks} gjorda. + + * Lite omorganisationer gjorda ig}r. En del grejer nedflyttade i + directories f|r att f} ett renare toppdir. + +Fri Jul 27 01:21:45 1990 Per Cederqvist (ceder at lage) + + * Nu {r funktionerna i services.h dokumenterade, i alla fall lite + grann. Kommentarerna finns i server/services.c. De borde v{l + kopieras till services.h ocks}. Vi f}r v{l se om jag hinner det + n}gon g}ng p} denna sida ny}r... + +Wed Jul 25 14:35:52 1990 Per Cederqvist (ceder at lave) + + * F|ljande filer installerade: + + /usr/local/etc/ramkomd + /usr/local/etc/updateLysKOM + /usr/local/bin/kompost + /usr/local/bin/komlisten + + * ramkomd sparar numera alla texter, m|ten och personer var 15:e + minut. Det {r programmet /usr/local/etc/updateLysKOM som kopplar + upp sig och skickar anropet kom_sync() som vem som helst kan + g|ra. (Man beh|ver inte ens vara inloggad). updateLysKOM startas + fr}n min crontab p} lave. stdout skickas till 2kom/stdout, + stderr till 2kom/stderr. Alla logg-meddelanden kommer till + stderr. + + Om ramkomd inte {r ig}ng f|rs|ker updateLysKOM starta om + ramkomd. + + Data lagras i filerna /usr/local/src/2kom/db/ramkomd-data och + ramkomd-backup. + +Tue Jul 24 13:37:03 1990 Per Cederqvist (ceder at lave) + + * komlisten - ett program f|r att lyssna p} de asynkrona + meddelanden som skickas. 'komlisten lave 5 pw' eller 'komlisten + lave'. Den f|rsta varianten loggar in som person nummer 5 med + l|sen 'pw'. P} s} s{tt f}r den se alla texter som skapas i m|ten + d{r p 5 {r medlem. + +Mon Jul 23 04:01:55 1990 Per Cederqvist (ceder at lave) + + * kompost - ett program f|r att kolla om man har n}gon post i kom. + 'kompost lave 5' ser efter hur m}nga ol{sta brev person 5 har p} + det kom som k|r p} lave. + +Sun Jul 22 02:17:57 1990 Per Cederqvist (ceder at lave) + + * I kom/isc-client/ ligger k{llkoden till klient-sidan. Synopsis: + + #define CLIENT + #include "/usr/local/2kom/services.h" + + cc main.o ... -L/usr/local/2kom -lyskom + + * isc b|rjar bli klart (tror jag). Jag har i alla fall lyckats + koppla upp en micro-klient mot servern och skapat en person och + ett m|tet, och l}tit personen g} med i m|tet. + +Fri Jul 20 01:00:00 1990 Thomas Bellman (bellman at laila) + + * Backup tagen av hela LysKOM p} Inge Wallins optiska disk. + F|rhoppningsvis {r det helt i on|dan... + +Tue Jul 17 15:19:29 1990 Per Cederqvist (ceder at lave) + + * kom-types.h: Sista (?) {ndringen i Person-structen: + confs och no_of_confs har slagits ihop till + Membership_list conferences. + + Nu har vi inga pekare i Person-structen. Alla 'array/listor' + ligger inbakade i en list-typ. Det {r bara f|rvirrande att ha + det p} olika s{tt. Jag har just suttit i ett halvt dygn och + letat felet innan jag kom p} att confs pekade p} en variabel + lista... + +Sun Jul 15 04:43:20 1990 Thomas Bellman (bellman at laila) + + * Eftersom serverskrivarna (l{s Ceder) hade en del underliga + |nskem}l om att f} anv{nda konstiga funktioner som smalloc och + annat f|r minneshantering {ven i str{ngfunktionerna, tvingar jag + dem nu att anropa funktionen s_set_storage_management() f|r att + ange vilka funktioner som ska anv{ndas i st{llet f|r de vanliga. + Tyv{rr m}ste jag sj{lv g|ra det ocks}, men det {r betydligt + snyggare {n det s{tt som det l|stes p} innan. + +Fri Jul 13 13:12:23 1990 Per Cederqvist (ceder at laila) + + * kom-types.h: Jag lade till ett antal bitar i Personal_flags och + Priv_bits f|r framtida bruk. + + * kom-types.h: Person-structen: f{ltet 'texts' har bytt namn och + typ till 'Text_list created_texts'. + + * OMORGANISATION!!! Saker som l}g i kom-types.h som ska se + olika ut f|r server och klient, {r flyttade fr}n + client/client-types.h resp. server/server-types.h tillbaka till + kom-types.h. client/client-types.h och server/server-types.h {r + borttagna. + +Sat Jul 7 07:44:45 1990 Per Cederqvist (ceder at lave) + + * Det gick inte alls bra. Tydligen m}ste filerna som man cat:ar + ihop utg} fr}n samma directory... :-( + + * TAGS-filerna: I varje directory g|rs en TAGS-fil p} de filer som + finns d{r. I kom:/ g|rs en total TAGS-fil genom att cat:a ihop + dom. Jag {r inte helt s{ker p} att det {r s} smart, men vi f}r + se hur det g}r. + +Thu Jul 5 13:13:41 1990 Per Cederqvist (ceder at laila) + + * services.h: Ny funktion: delete_text(Text_no text_no); + +Tue Jul 3 01:12:50 1990 Thomas Bellman (bellman at laila) + + * services.h: Ny maskbit f|r get_person_stat(), GETP_READ_TEXTS, + som inneb{r att man vill ha listorna av l{sta texter tillsammans + med medlemskapslistan. Dessa ska inte skickas med om man inte + explicit ber om det; det finns query_unread(). + +Wed Jun 27 05:13:01 1990 Thomas Bellman (bellman at lave) + + * services.h: Alla funktionsdeklarationer {r omg{rdade av makrot + KOM_ som ser till att funktionerna heter 'kom_foo' p} + klientsidan och 'foo' p} serversidan. Detta {r beroende p} om + makrona CLIENT respektive SERVER {r definierade. Detta f|r att + vi ska slippa ha tv} services.h att underh}lla. + +Wed Jun 6 00:14:35 1990 Per Cederqvist (ceder at laila) + + * services.h: [ndrade 'String' till 'const String' i alla + funktionshuvuden. + + * glue: Directory som inneh}ller klister f|r att klistra ihop en + klient med servern. + + * services.h: Alla funktioner som f|rut hette 'foo' heter nu + 'kom_foo'. Anledningen {r att man vill kunna l{nka ihop klienten + och servern och f} ett singeluserkom innan Peter {r klar med + sitt paket... ;-) + +Tue May 29 16:17:53 1990 Per Cederqvist (ceder at lave) + + * services.h {r nu splittrad. server/services.h inneh}ller + funktionerna som de ser ut p} server-sidan, services.h som de + ser ut f|r klienten. + +Mon May 28 23:02:24 1990 Thomas Bellman (bellman at laila) + + * Summarize-Headers: Shell-script f|r att sammanfatta inneh}llet + i en .h-fil. + + * (Egentligen den 26:e) FileList inf|rd! En fil som inneh}ller + beskrivningar p} alla filer i ett dir. Shell-scriptet + List-Files f|r att lista vilka filer som inte {r beskrivna. + + * s-string.[ch]: Fler funktioner: s_skip_blanks(), s_strtol(). + +Sat May 26 15:02:48 1990 Per Cederqvist (ceder at laila) + + * Mailinglist: Ny fil som inneh}ller email-adresser p} alla de som + svarat p} mitt inl{gg i Linus-kom om mailinglistan. Det vore + fint om n}gon skickar ett mail till dom n{r LysKom {r ig}ng... + Tills vidare tar jag p} mig ansvaret f|r utskicken. + +Sat May 26 01:36:02 1990 Thomas Bellman (bellman at laila) + + * s-string.[hc]: Nya funktioner s_strhead() och s_usr_strhead(). + Testar om en str{ng {r en b|rjan p} en annan. + +Fri May 25 02:37:55 1990 Per Cederqvist (ceder at lave) + + * s-string.h: Nytt macro s_empty(str) som returnerar TRUE omm str + {r tom. + + * kom-types.h: Tog bort f{ltet 'Conf_type type' ur + Membership-structen. Det visar sig att det {r b{ttre att cacha + Conf_type tillsammans med namnet. + +Tue May 15 17:49:47 1990 Per Cederqvist (ceder at laila) + + * kom-types.h: Info_type och Info_datum: Ny typ: sent_at. + S} att man vet n{r en text {r skickad n{r den skickas i efterhand. + +Mon May 14 08:59:14 1990 Thomas Bellman (bellman at laila) + + * Biblioteket kom:/ansi-include skapat. Detta bibliotek + genoms|kes av cpp enligt Makefile (Template). I biblioteket + finns {n s} l{nge stdio.h, malloc.h och string.h. Strunta i + filen kom:/ansi.h. NU ska vi v{l {ntligen slippa ifr}n alla + problem vi haft med include-filer och odeklarerade funktioner. + Fyll g{rna p} med fler generella .h-filer. + +Sun May 13 23:12:23 1990 Per Cederqvist (ceder at lage) + + * kom-errno.[hc]: s} heter den nu. + +Sun May 13 23:05:23 1990 Thomas Bellman (bellman at laila) + + * s-string.[ch]: Skapad. V}r egen str{ngtyp (String) samt + funktioner f|r att manipulera dessa. + +Thu May 10 16:27:35 1990 Per Cederqvist (ceder at lage) + + * config.h: DEFENSIVE_CHECKS - definierad om vi {r defensiva. + +Wed May 9 17:34:31 1990 Linus Tolke (linus at laila) + + * Person-strukten anv{nder String och Mark_list ist{llet f|r + char * och Mark + + * Jag justerade ordningen f|r filerna som argument till etags. + Jag vill n{mligen n} typen Person p} mindre {n 3 steg! + +Tue May 8 19:36:44 1990 Per Cederqvist (ceder at lage) + + * bool heter numera Bool. + + * Ny typ: Success. Att anv{ndas av alla funktioner som returnerar + OK eller FAILURE. + +Fri May 4 01:25:23 1990 Per Cederqvist (ceder at lage) + + * services.h: create_conf tar nu {ven Conf_type type som argument. + P} s} vis kan ett hemligt m|te vara hemligt fr}n b|rjan. + +Thu May 3 00:56:35 1990 Per Cederqvist (ceder at lage) + + * kom-types.h: Nytt f{lt i Membership: Conf_type type + + * jin_errno heter numera kom_errno. + + * query_unread_mail heter numera query_unread och {r lite mer + flexibel - man kan fr}ga hur mycket ol{sta en viss person har + i ett visst m|te. + +Thu Apr 26 01:52:51 1990 Thomas Bellman (bellman at lage) + + * P{rm f|r listningar inskaffad. Gamla listningar av 2kom/ och + 2kom/client/ finns insatta. N{r ni tar ut listningar, s{tt in + dem i p{rmen. Den ligger i hyllan ovanf|r LLL. En gul p{rm + m{rkt "LysKOM". Observera att listningarna som sitter i den + just nu {r inaktuella, p g a.... + + * OMORGANISATION!!! Saker som l}g i kom-types.h som ska se + olika ut f|r server och klient, {r flyttade till + client/client-types.h resp. server/server-types.h. Samtidigt + togs types.h bort. + + * Listor i Person- och Conference-structarna {r nu egna typer. + + * 'get_person_stat()' och 'get_conf_stat()' tar numera en pekare + till en area d{r resultatet ska l{ggas. Dessutom skickar man + med en mask som talar om hur mycket information man vill ha. + +Wed Apr 25 02:38:32 1990 Thomas Bellman (bellman at laila) + + * Lade till 'footnote to' och 'footnote in' i misc_info. + + * Skapade 'kom-types.c' som typiskt inneh}ller konstanter och + annat som man tycker borde ligga i en .h-fil, men som inte kan + g|ra det om filen inkluderas i mer {n en k{llkodsfil. + +Wed Apr 25 00:49:01 1990 Per Cederqvist (ceder at laila) + + * services.h: add_member tar numera tv} parametrar f|r att ange + prioritet p} m|tet. add_member anv{nds {ven f|r att {ndra + prioritet p} ett m|te man redan {r med i. + +Sat Apr 21 13:52:12 1990 Per Cederqvist (ceder at lave) + + * Fixade en Makefile som generarar en TAGS-fil som inneh}ller allt + till servern. + + * kom-types.h: Nya privilegiebitar: admin och statistic. + +Fri Apr 20 14:09:26 1990 Per Cederqvist (ceder at lage) + + * kom-types.h: Ny typ Conf_nos. + + * services.h: Ny definition av lookup_name. Nu returneras en lista + med alla konferenser som matchar argumentet. + + * P} beg{ran av Bellman {r nu jin_errno en enum. + +Thu Apr 19 02:47:05 1990 Per Cederqvist (ceder at lave) + + * kom-types.h: Conf_type: nytt f{lt "no_stat". + Sec_bits: ny typ som anger vad en person vill h}lla + hemligt. + Person: nytt f{lt "flags". + +Wed Apr 18 00:08:22 1990 Per Cederqvist (ceder at lage) + + * services.h: get_marks har nu ingen parameter. Man kan bara titta + p} sina egna markeringar. + + * kom-types.h inkluderar nu {ven <stddef.h> + + * Skapade jin_errno.h. + + * services.h: alla funktioner som returnerade en struct + returnerar nu en pekare till motsvarande struct. + + * Ny funktion i services: query_unread_mail. (Se m 230) + diff --git a/FileList b/FileList new file mode 100644 index 0000000000000000000000000000000000000000..55815ac0e3a0363bb4cd0ac8d93a7d71b21fc742 --- /dev/null +++ b/FileList @@ -0,0 +1,136 @@ +(Hey, Emacs, this is a -*- Indented-text -*- file!) + +* ansi-include/ + Directory containing ANSI-fied header files for the standard + libraries. + + +* ChangeLog + Log file where the progressing work and changes are sporadically + documented. You are encouraged to add an entry in this file + whenever you change something in this directory. + + +* client/ + Directory containing a TTY-based client for LysKOM, very similar to + the original KOM program from QZ. + + +* config.h + Configuration parameters for compiling. Contains among other + things all the stupid limits you really want to be without, all the + smart limits that has to be there to make it impossible to crash + the server, and lots of constants and configuration options. + + +* debug.h + Some #defines for debugging purposes. + + +* doc/ + Documentation of LysKOM; both internal and external. Also some + random thoughts members of the development team wanted to write + down during development. + + +* FileList + This file, describing all the files. + + +* kom-errno.c + Defines the variable 'kom_errno' and the function 'kom_perror()'. + Used for error handling in LysKOM. + + +* kom-errno.h + Defines the type 'Kom_err' and declares the variable 'kom_errno'. + The server sets the value of 'kom_errno' when an error occurs. + The function 'kom_perror()' is declared. + + +* kom-types.h + Declares the types used by LysKOM. Here are the types that are + common to both the server and the client. Types that look + different to the server and the client, are found in + 'server/server-types.h' and 'client/client-types.h' respectively. + + +* ldb/ + Directory containing the low-level database routines for the LysKOM + server. 'ldb' stands for Lyskom DataBase. + + +* List-Files + Shell script to list the files in this directory not documented in + the file 'FileList' (the one you are reading now). + + +* Mailinglist + List of mail addresses of people who want to be informed of the + progress of LysKOM. + + +* Makefile + Exactly what the name says. + + +* misc-types.h + Miscellaneous types and constants that are useful in many places in + LysKOM, but are not very LysKOM-specific. + + +* s-collat-tables.c + Collating tables used for the 's_usr_strcmp()' and + 's_usr_strhead()' functions in 's-string.h' + + +* s-collat-tables.h + Header file for 's-collat-tables.c' + + +* s-string.c + Routines for manipulating objects of type String as defined in + 's-string.h' + + +* s-string.h + Header file for 's-string.c' + Definies our own string type 'String', and declares the functions + in 's-string.c' + + +* server/ + Directory containing the LysKOM server, except for the low-level + database routines, which for historical reasons are in the separate + directory 'ldb/'. + + +* services.h + Declares all the services available from the LysKOM server. + + +* Summarize-Headers + Since we write our .h files with documentation in line, they + tend to get rather long, and it gets somewhat difficult to get + a quick overview of what functions are declared in the file. + This script cuts out all the "unnecessary" information: all + comments and all preprocessor lines (starting with #). + + +* TAGS + Tags table for use with Emacs. + + +* Template + Template for automatically generating 'Makefile'. 'Makefile' is + updated with the command 'make depend'. This should be given + whenever a change to 'Template' is done, or any new files are + added, or any dependecies are changed. Dependencies for normal C + files are generated automatically by this. + If 'Makefile' should become garbled, copy 'Template' to 'Makefile' + and do a 'make depend'. + + +* test-services/ + Directory containing programs to test parts of the server. Used by + ceder, and should not be distributed. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ab919c7b51111390a9a004422ceb557b403440cc --- /dev/null +++ b/Makefile @@ -0,0 +1,71 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR := $(shell pwd) +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + +SUBDIRS = doc include junk lib scripts src + +all: + for i in $(SUBDIRS) ; \ + do \ + echo making all in directory $$i; \ + (cd $$i; $(MAKE) all) \ + done + + +install: + for i in $(SUBDIRS) ; \ + do \ + echo making install in directory $$i; \ + (cd $$i; $(MAKE) install) \ + done + +depend: + (cd src/include; make install) + (cd src/libraries; make install-headers) + for i in $(SUBDIRS) ; \ + do \ + echo making depend in directory $$i; \ + (cd $$i; $(MAKE) depend); \ + done + + +clean: + rm -vf *~ core + for i in $(SUBDIRS); \ + do \ + echo making clean in directory $$i; \ + (cd $$i; $(MAKE) clean) \ + done + +war: + @echo "Thou shalt not make war. Makest love instead!" + +love: + @clear; cat /usr/local/lib/makelove diff --git a/doc/man/man3/isc3.x b/doc/man/man3/isc3.x new file mode 100644 index 0000000000000000000000000000000000000000..aec549f6ec54f74a3c7d5eeef597cf75afdc78bd --- /dev/null +++ b/doc/man/man3/isc3.x @@ -0,0 +1,186 @@ +.\" $Copyright: $ +.\" Copyright (c) 1991 Lysator Computer Club, Linkoping University, Sweden +.\" All rights reserved +... +.V= $Header: /home/ceder/convert-lyskomd/cvsroot/lyskom-server/doc/man/man3/Attic/isc3.x,v 0.1 1991/08/12 17:39:55 ceder Exp $ +.TH ISC 3X "\*(V)" "LUNATIX" +.SH NAME +isc_initialize, isc_shutdown, isc_listen, isc_unlisten, +isc_opentcp, isc_openfile, isc_openfd, isc_close, +isc_sessions, isc_getnextevent, isc_dispose, +isc_flush, isc_write, isc_putc, isc_printf, +isc_allocmsg, isc_reallocmsg, isc_freemsg, isc_mkstrmsg, +isc_setmaxmsgsize, isc_setallocfn, isc_setlogfn, isc_setabortfn +.SH FUNCTIONS +.nf +.B IscMaster * +.B " isc_initialize (IscConfig *cfg)" +.PP +.B void +.B " isc_shutdown(IscMaster *mcb)" +.PP +.B int +.B " isc_listen(IscMaster *mcb, int port);" +.PP +.B void +.B " isc_unlisten(IscMaster *mcb, int port);" +.PP +.B "IscSession *" +.B " isc_opentcp(IscMaster *mcb, const char *host, int port)" +.PP +.B "IscSession *" +.B " isc_openfile(IscMaster *mcb, const char *path, int mode)" +.PP +.B "IscSession *" +.B " isc_openfd(IscMaster *mcb, int fd)" +.PP +.B "void" +.B " isc_close (IscSession *scb)" +.PP +.B "int" +.B " isc_sessions (IscMaster *mcb)" +.PP +.B "IscEvent *" +.B " isc_getnextevent (IscMaster *mcb, long timeout)" +.PP +.B "void" +.B " isc_dispose (IscEvent *ecb)" +.PP +.B "void" +.B " isc_flush (IscSession *scb)" +.PP +.B "int" +.B " isc_write (IscSession *scb, const void *buf, size_t len)" +.PP +.B "int" +.B " isc_printf (IscSession *scb, const char *format, ...)" +.PP +.B "int" +.B " isc_putc (int chr, IscSession *scb)" +.PP +.B "IscMessage *" +.B " isc_allocmsg(size_t size);" +.PP +.B "IscMessage *" +.B " isc_reallocmsg(IscMessage *msg, size_t size);" +.PP +.B "void" +.B " isc_freemsg(IscMessage *msg);" +.PP +.B "IscMessage *" +.B " isc_mkstrmsg(const char *str);" +.PP +.B "void" +.B " isc_setmaxmsgsize (IscMaster *mcb, size_t size)" +.PP +.B "void" +.B " isc_setlogfn (void (*logfnp)(const char *fmt, va_list AP))" +.PP +.B "void" +.B " isc_setallocfn (void * (*mallocfn)(size_t size)," +.B " void * (*reallocfn)(void *buf, size_t size)," +.B " void (*freefn)(void *buf))" +.PP +.B "void" +.B " isc_setabortfn (void (*abortfn)(const char *msg))" +.SH TYPES +.nf +.B typedef void IscConfig; +.PP +.B typedef enum +.B { +.B " ISC_EVENT_ERROR," +.B " ISC_EVENT_TIMEOUT," +.B " ISC_EVENT_LOGIN," +.B " ISC_EVENT_LOGOUT," +.B " ISC_EVENT_MESSAGE," +.B "} IscEventType;" +.PP +.B typedef enum +.B { +.B " ISC_TYPE_UNKNOWN," +.B " ISC_TYPE_TCP," +.B " ISC_TYPE_FILE" +.B "} IscSessionType;" +.PP +.B typedef struct isc_msg +.B { +.B " int size;" +.B " int length;" +.B " char *buffer;" +.B } IscMessage; +.PP +.B typedef struct isc_mcb +.B { +.B " int port;" +.B " int fd;" +.B " int maxmsgsize;" +.B " int maxqueuedsize;" +.B " int maxdequeuelen;" +.B " struct isc_scb *sessions;" +.B } IscMaster; +.PP +.B typedef struct isc_scb +.B { +.B " struct isc_scb * prev;" +.B " struct isc_scb * next;" +.B " IscMaster * mcb;" +.B " IscSessionType type;" +.B " int fd; +.B " IscMsgQueue * rd_msg_q;" +.B " IscMsgQueue * wr_msg_q;" +.B " char sendbuf[2048];" +.B " int sendindex;" +.B " union" +.B " {" +.B " struct" +.B " {" +.B " char * hostname;" +.B " int rport;" +.B " int lport;" +.B " } tcp;" +.B " struct" +.B " {" +.B " char * pathname;" +.B " int openmode;" +.B " } file;" +.B " } info;" +.B " int kill_him;" +.B " time_t logintime;" +.B " struct" +.B " {" +.B " struct" +.B " {" +.B " long bytes;" +.B " long packets;" +.B " } rx, tx;" +.B " } stats;" +.B "" +.B " ISC_UDGTYPE * udg; /* Reserved for user defined usage */" +.B "} IscSession;" +.PP +.B typedef struct isc_ecb +.B { +.B " IscEventType event;" +.B " IscSession * session;" +.B " IscMessage * msg;" +.B } IscEvent; +.SH DESCRIPTION +These functions implement an interface to the TCP/IP streams facitiliy. +The functions are obtained with the loader option +.BR \-lisc . +(More to come here...) +.PP +.SH DIAGNOSTICS +(And here... :\-) +.PP +.SH BUGS +Hehe... I'm sure they exists... +.SH GUILTY +Peter Eriksson <pen@lysator.liu.se> & +Per Cederqvist <ceder@lysator.liu.se> + + +ISC is Copyright (c) 1991 Lysator Computer Club, Linkoping University, Sweden, +in cooperation with the International Syndicate of Computation. +All rights reserved. diff --git a/foo b/foo new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/Depend.make b/scripts/Depend.make new file mode 100644 index 0000000000000000000000000000000000000000..7f21f9e84f1c20ca4dc1d13084df038596c18398 --- /dev/null +++ b/scripts/Depend.make @@ -0,0 +1,19 @@ +depend: + ${SED} '/^# OBJECTS: @@@* #$$/q' Makefile > temp-Makefile + echo '# This line is generated by "make depend"'>>temp-Makefile + echo -n 'OBJECTS = ' >>temp-Makefile + ls *.c | ${AWK} 'BEGIN { pos = 10; } \ + { sub(/\.c$$/, ".o"); \ + pos += length($$0) + 1; \ + if (pos >= 75) \ + { printf("\\\n\t"); \ + pos = 9 + length($$0); \ + } \ + printf ("%s ", $$0); \ + }' >>temp-Makefile + echo >>temp-Makefile + ${SED} '/^# RULES: @@@* #$$/,/^# DEPENDENCIES: @@@* #$$/!d' \ + Makefile >>temp-Makefile + echo >>temp-Makefile + gcc -M -DCLIENT ${INCLUDES} *.c >>temp-Makefile + mv temp-Makefile Makefile diff --git a/scripts/List-Files b/scripts/List-Files new file mode 100755 index 0000000000000000000000000000000000000000..292acbf6a0c160fe9e0371385776f653d8fad09f --- /dev/null +++ b/scripts/List-Files @@ -0,0 +1,25 @@ +#!/bin/sh + +# Lists the differences between the file 'FileList' and what's +# actually in the current directory. + +# Change to the directory specified as first parameter. +cd ${1-.} + +# Get the names of some temporary files. +FILE1=/tmp/LysKOM.$$.fl # The files in 'FileList' +FILE2=/tmp/LysKOM.$$.ls # The files in this directory + +# First find out what files are described in 'FileList'. +egrep '^\*' FileList | sed 's/^\* //' >$FILE1 + +# Find the files in this directory that we are interested in. +# Remove trailing *'s, since those are generated by 'ls -F' +# Files ending in .o and ~ are not interesting either. +ls -F | sed 's/\*$//' | egrep -v '\.o$|~$' | sort -f >$FILE2 + +# Then compare that list to the output from 'ls(1)' +diff $FILE1 $FILE2 + +# Clean up +rm $FILE1 $FILE2 diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b23b3f02449b28289324f4381e8b007d2f1bf017 --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,6 @@ +all:; +depend:; +install:; + +clean: + rm -vf *~ core diff --git a/scripts/Parallell-depend.make b/scripts/Parallell-depend.make new file mode 100644 index 0000000000000000000000000000000000000000..b3e9f6af9951da44cf66e6064ed14ca69ff12ae9 --- /dev/null +++ b/scripts/Parallell-depend.make @@ -0,0 +1,28 @@ +# temp-B-Makefile temp-C-Makefile \ +# temp-D-Makefile temp-E-Makefile + +depend: temp-A-Makefile + rm -f dependencies + cat temp-?-Makefile >dependencies + rm temp-?-Makefile temp-?-files + echo depend ready. + +temp-A-Makefile: c-indexes specials + -$(CC) -M ${TARGET} ${INCLUDES} `cat temp-A-files` >temp-A-Makefile + +temp-B-Makefile: c-indexes specials + -$(CC) -M ${TARGET} ${INCLUDES} `cat temp-B-files` >temp-B-Makefile + +temp-C-Makefile: c-indexes specials + -$(CC) -M ${TARGET} ${INCLUDES} `cat temp-C-files` >temp-C-Makefile + +temp-D-Makefile: c-indexes specials + -$(CC) -M ${TARGET} ${INCLUDES} `cat temp-D-files` >temp-D-Makefile + +temp-E-Makefile: c-indexes specials + -$(CC) -M ${TARGET} ${INCLUDES} `cat temp-E-files` >temp-E-Makefile + +c-indexes: + ls *.c|${AWK} '{ a[i++] = $$1; } \ + END { for ( j = 0; j < i; j++ ) \ + print a[j] > sprintf("temp-%c-files", 65 + j % 5); } diff --git a/scripts/RCS-depend.make b/scripts/RCS-depend.make new file mode 100644 index 0000000000000000000000000000000000000000..328384275a588c9854cfca92d22e8fb617cf16bd --- /dev/null +++ b/scripts/RCS-depend.make @@ -0,0 +1,27 @@ +depend: temp-A-Makefile temp-B-Makefile temp-C-Makefile temp-D-Makefile \ + temp-E-Makefile + rcs -l dependencies + rm -f dependencies + cat temp-?-Makefile >dependencies + rm temp-?-Makefile temp-?-files + echo " " | ci dependencies + +temp-A-Makefile: c-indexes + gcc -M ${TARGET} ${INCLUDES} `cat temp-A-files` >temp-A-Makefile + +temp-B-Makefile: c-indexes + gcc -M ${TARGET} ${INCLUDES} `cat temp-B-files` >temp-B-Makefile + +temp-C-Makefile: c-indexes + gcc -M ${TARGET} ${INCLUDES} `cat temp-C-files` >temp-C-Makefile + +temp-D-Makefile: c-indexes + gcc -M ${TARGET} ${INCLUDES} `cat temp-D-files` >temp-D-Makefile + +temp-E-Makefile: c-indexes + gcc -M ${TARGET} ${INCLUDES} `cat temp-E-files` >temp-E-Makefile + +c-indexes: sources + echo ${SRCS}|tr " " \\012 |${AWK} '{ a[i++] = $$1; } \ + END { for ( j = 0; j < i; j++ ) \ + print a[j] > sprintf("temp-%c-files", 65 + j % 5); } diff --git a/scripts/Summarize-Headers b/scripts/Summarize-Headers new file mode 100755 index 0000000000000000000000000000000000000000..ca5a05c320b46a2fbd01ae8b022d2d4fbe9d4269 --- /dev/null +++ b/scripts/Summarize-Headers @@ -0,0 +1,43 @@ +#!/bin/sh + +# Summarize a .h file + +# Since we write our .h files with documentation in line, they +# tend to get rather long, and it gets somewhat difficult to get +# a quick overview of what functions are declared in the file. +# This script cuts out all the "unnecessary" information. + +AWK=gawk + +$AWK '/^[ \t]*#[ \t]*define/ { print $0 ; + define = 1 ; + next ; + } + define != 0 { if (substr($0, length(), 1) == "\\") + { + printf ("\n") ; + next ; + } + else { + printf ("\n") ; + define = 0 ; + next ; + } + } + /^\/\*/,/\*\/$/ { printf ("\n") ; + next ; + } + /\/\// { next ; } + (define == 0) && \ + (comment == 0) { print $0 ; } + /\/\*/ { comment = 1 ; } + /\*\// { comment = 0 ; } +' $1 | +$AWK 'BEGIN { blank_lines = 0; } + $1 == "" { if (blank_lines++ == 0) + print $0; + } + $1 != "" { print $0; + blank_lines = 0; + } +' diff --git a/scripts/import.make b/scripts/import.make new file mode 100644 index 0000000000000000000000000000000000000000..2e39c9213cac0eb6d9ef6076cc4193733c1d74e7 --- /dev/null +++ b/scripts/import.make @@ -0,0 +1,67 @@ +# This file is included by all Makefiles in the LysKOM hierarchy. +# It gives default values for all variables that is normally used. +# TOPDIR and SCRIPTDIR must be set before this file is included. +# If any of the variables are defined in the environment, that value +# will override the value that is set here. +# +# ceder is guilty. +# + +ifndef SHELL +SHELL=/bin/sh +endif + +ifndef INCLUDEDIR +INCLUDEDIR = $(TOPDIR)/include +endif + +ifndef LIBDIR +LIBDIR = $(TOPDIR)/lib +endif + +ifndef ANSIDIR +ANSIDIR = $(INCLUDEDIR)/ansi +endif + +# Used programs. + +ifndef AWK +AWK = gawk +endif + +ifndef SED +SED = /usr/bin/sed +endif + +ifndef CC +CC = /usr/gnu/bin/gcc -ansi +endif + +ifndef RM +RM = /usr/gnu/bin/rm -vf +endif + +# Flags to the C compiler + +ifndef INCLUDES +INCLUDES = -I$(ANSIDIR) -I$(INCLUDEDIR) +endif + +ifndef OPTIMIZE-FLAGS +OPTIMIZE-FLAGS = -O +endif + +ifndef MISC-CFLAGS +MISC-CFLAGS = -g -Wall +endif + +ifndef LDFLAGS +# -h flag makes NULL pointer references generate runtime errors +LDFLAGS = -h -L$(LIBDIR) +endif + +# Force CFLAGS to always follow the settings of INCLUDES, +# OPTIMIZE-FLAGS and MISC-CFLAGS. +# Set PIPE=-pipe if you want to. + +CFLAGS = $(INCLUDES) $(OPTIMIZE-FLAGS) $(MISC-CFLAGS) $(PIPE) $(TARGET) diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..338aeb482fc124575cb8ee3192b81f58848dba22 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,38 @@ +# All directories that make should traverse to when doing clean etc. +# Note htat libraries MUST be made before the rest. Otherwise you will +# be linking with old versions... + +SUBDIRS = include libraries server komutils clients + +all: + for i in $(SUBDIRS) ; \ + do \ + echo making all in directory $$i; \ + (cd $$i; $(MAKE) all) \ + done + + +install: + for i in $(SUBDIRS) ; \ + do \ + echo making install in directory $$i; \ + (cd $$i; $(MAKE) install) \ + done + + +depend: + for i in $(SUBDIRS) ; \ + do \ + echo making depend in directory $$i; \ + (cd $$i; $(MAKE) depend) \ + done + + +clean: + rm -vf *~ core + for i in $(SUBDIRS); \ + do \ + echo making clean in directory $$i; \ + (cd $$i; $(MAKE) clean) \ + done + diff --git a/src/include/Makefile b/src/include/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..45a81015942abedc44931b87cfa9cac8e16f1fbe --- /dev/null +++ b/src/include/Makefile @@ -0,0 +1,76 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR = /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +TARGET = -DCLIENT + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + +SUBDIRS = ansi server + +INSTALL-HDRS = $(wildcard *.h) + +all: + for i in $(SUBDIRS); \ + do \ + echo making all in directory $$i; \ + (cd $$i; $(MAKE) all); \ + done + + + +.PHONY : install +install: + (cd $(INCLUDEDIR); $(RM) $(INSTALL-HDRS)) + cp $(INSTALL-HDRS) $(INCLUDEDIR)/ + for i in $(SUBDIRS); \ + do \ + echo making install in directory $$i; \ + (cd $$i; $(MAKE) install); \ + done + +clean: + rm -vf ${OBJECTS} *~ core temp-Makefile Distfile *.o + for i in $(SUBDIRS); \ + do \ + echo making clean in directory $$i; \ + (cd $$i; $(MAKE) clean); \ + done + + +depend: + for i in $(SUBDIRS); \ + do \ + echo making depend in directory $$i; \ + (cd $$i; $(MAKE) depend); \ + done + >dependencies + +specials:; + +include dependencies diff --git a/src/include/compiler.h b/src/include/compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..ceeb6583d160ab8117cd75a17d2dbffc794f67ab --- /dev/null +++ b/src/include/compiler.h @@ -0,0 +1,41 @@ +/* + * compiler.h + * Defines different macros depending on the compiler to + * portably use features of different compilers, like the + * '__inline__' keyword in GCC. + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + +#ifndef SPECIAL_H_ALREADY_INCLUDED__ +#define SPECIAL_H_ALREADY_INCLUDED__ + + +#ifdef __GNUC__ + +# define Inline __inline__ /* Inline function */ +# define Volatile volatile /* Function does not return */ + +#else + +# define Inline +# define Volatile + +#endif + + +#endif /* SPECIAL_H_ALREADY_INCLUDED__ */ diff --git a/src/include/config.h b/src/include/config.h new file mode 100644 index 0000000000000000000000000000000000000000..171752e255a067706ebf7583d8fb75dc9954713f --- /dev/null +++ b/src/include/config.h @@ -0,0 +1,133 @@ +/* + * config.h + * + * Configuration parameters for compiling. Contains among other + * things all the stupid limits you really want to be without, all the + * smart limits that has to be there to make it impossible to crash + * the server, and lots of constants and configuration options. + */ + + +#define DEBUG /* We're still debugging and want traces. */ + +/* + * Add some checks that really shouldn't be necessary. + */ +#define DEFENSIVE_CHECKS + + +/* Collating sequence used. */ +#define DEFAULT_COLLAT_TAB swedish_collate_tab + + + +/* The file kom_perror prints to. */ +/* Yes! This should be stdout. At least during testing and debugging! /ceder */ + +#define kom_errout stdout + +/* + * Security options (these must be #defines since they are used inside a + * 'const' definition in kom-types.c). + */ +#define ANYONE_CAN_CREATE_NEW_PERSONS TRUE /* Can a created person */ + /* create other persons? */ +#define CREATE_PERSON_BEFORE_LOGIN TRUE /* Can a person create himself? */ +#define ANYONE_CAN_CREATE_NEW_CONFS TRUE +#define DEFAULT_CHANGE_NAME TRUE /* Everyone is normally allowed */ + /* to change their own name. */ + +/* + * The following are constants which can not be changed without rewriting + * some of the code. + */ +#define PROTOCOL_NUMBER_BASE 10 /* The number base used in all communication + * between server and clients. */ + + +/* Where to save things. These are used by ramkomd. */ + +extern const char *DEFAULT_DBASE_DIR; +extern const char *DATAFILE_NAME; +extern const char *BACKUPFILE_NAME; +extern const char *TEXTFILE_NAME; +extern const char *STATISTIC_NAME; +extern const char *PID_NAME; +extern const char *MEMUSE_NAME; + +/* Communications */ + +extern const char * DEFAULT_CLIENT_SERVICE; +extern const char * DEFAULT_MUX_SERVICE; + +#if 0 +extern const int IN_CLIENT_PORT; /* Which port does LysKOM listen to? */ +extern const int IN_MUX_PORT; /* Which port does LysKOM listen to? */ +#endif + +/* + * The following should always be true: + * SYNCTIMEOUT <= GARBTIMEOUT <= TIMEOUT + * Times in milliseconds. + */ +extern const int TIMEOUT; /* Timeout to select() when totally idle. */ +extern const int GARBTIMEOUT; /* Timeout to select() when garbing texts + but not syncing. */ +extern const int SYNCTIMEOUT; /* Timeout to select() when syncing. */ + +extern const int GARB_INTERVAL; /* In minutes. */ +extern const int SYNC_INTERVAL; /* In minutes. */ +extern const int SYNC_RETRY_INTERVAL; /* In minutes. */ + +/* Size of the cache. (only applies to diskomd). */ + +extern const int CACHE_CONFERENCES; +extern const int CACHE_PERSONS; +extern const int CACHE_TEXT_STATS; + +/* String limits */ + +extern const int CONF_NAME_LEN; /* Conference (and Person) name */ +extern const int PWD_LEN; /* Password. It is not guaranteed that all + chars are significant. */ +extern const int WHAT_DO_LEN; /* what_am_i_doing */ +extern const int USERNAME_LEN; /* Max login-id from clients */ +extern const int TEXT_LEN; /* Max len of a text. */ +extern const int BROADCAST_LEN; /* Max len of a broadcast message */ + +/* Text_stat limits */ + +extern const int MAX_MARKS_PERSON; /* Max marks per person */ +extern const int MAX_MARKS_TEXT; /* Max marks per text */ +extern const int MAX_RECIPIENTS; /* Max recipients/cc_recipients per text */ +extern const int MAX_COMM; /* Max number of comments to a text */ +extern const int MAX_FOOT; /* Max number of footnotes to a text */ +extern const int MAX_CREA_MISC; /* Sum of recipients, cc_recipients, comm_to + * and footn_to must not exceed MAX_CREA_MISC + * when the text is created. */ + +/* + * Some other limits + */ +extern const int MAX_NO_OF_CONNECTIONS; /* the maximum number of persons + * that can use Kom simultaneously */ +extern const int MARK_AS_READ_CHUNK; /* You can't mark more than this many + * texts as read in one call. */ + +/* + * Max number of nested super_confs a message will be forwarded before + * the server gives up. + */ +extern const int MAX_SUPER_CONF_LOOP; + + +extern const int DEFAULT_NICE; /* Number of days a text normally lives. */ + +/* Max entries in the per-client transmit queue */ +extern const int MAXQUEUEDSIZE; + +/* Max entries in the per-client transmit queue to send at any one time */ +extern const int MAXDEQUEUELEN; + +/* What is whitespace? */ +extern const unsigned char *WHITESPACE; diff --git a/src/include/debug.h b/src/include/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..312a3ec966cf6c2feaadcb4caca19dd5e852b635 --- /dev/null +++ b/src/include/debug.h @@ -0,0 +1,14 @@ +#include "config.h" /* DEBUG is defined there */ +#ifdef DEBUG +#define BUG(s) if (buglevel > 0) printf s ; +#define VBUG(s) if (buglevel > 1) printf s ; +#define BUGSTR(str) if (buglevel > 0) s_puts(str) +#define VBUGSTR(str) if (buglevel > 1) s_puts(str) +#define BUGDECL extern int buglevel +#else +#define BUG(s) +#define VBUG(s) +#define BUGSTR(str) +#define VBUGSTR(str) +#define BUGDECL +#endif diff --git a/src/include/dependencies b/src/include/dependencies new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/include/kom-errno.h b/src/include/kom-errno.h new file mode 100644 index 0000000000000000000000000000000000000000..4588c5dc5d24aaf3bba1ffdca73bb9863134c867 --- /dev/null +++ b/src/include/kom-errno.h @@ -0,0 +1,86 @@ +/* + * kom_errno.h + * + * Created by ceder 1990-04-18 + * + * The values that kom_errno can take. + */ + + +#ifndef _KOM_ERRNO_ALREADY_INCLUDED__ +#define _KOM_ERRNO_ALREADY_INCLUDED__ + +#include <sys/types.h> + + +typedef enum +{ + KOM_NO_ERROR = 0, /* No error has occured */ + KOM_NOT_IMPL = 2, /* Not implemented yet */ + KOM_OBSOLETE = 3, /* No longer implemented */ + KOM_PWD = 4, /* Wrong/illegal password */ + KOM_LONG_STR = 5, /* String too long */ + KOM_LOGIN = 6, /* Not logged in. */ + KOM_LOGIN_DISALLOWED = 7, /* System is in 'singel-user mode' */ + KOM_CONF_ZERO = 8, /* Attempt to use conference number 0. */ + KOM_UNDEF_CONF = 9, /* Undefined or secret conference */ + KOM_UNDEF_PERS = 10, /* Undefined or secret person */ + KOM_ACCESS = 11, /* No 'read/write permission' */ + KOM_PERM = 12, /* No permission */ + KOM_NOT_MEMBER = 13, /* Not member in conf */ + KOM_NO_SUCH_TEXT = 14, /* No such global text_no, or no access */ + KOM_TEXT_ZERO = 15, /* Can't use text no 0 */ + KOM_NO_SUCH_LOCAL_TEXT = 16, /* No such local text_no */ + KOM_LOCAL_TEXT_ZERO = 17, /* Can't use local text no 0 */ + KOM_BAD_NAME = 18, /* Too short/long or contains illegal chars */ + KOM_INDEX_OUT_OF_RANGE = 19, /* */ + KOM_CONF_EXISTS = 20, /* Already exists */ + KOM_PERS_EXISTS = 21, /* Already exists */ + KOM_SECRET_PUBLIC = 22, /* Cannot be secret and !rd_prot */ + KOM_LETTER_BOX = 23, /* Cannot change letter_box flag */ + KOM_LDB_ERR = 24, /* Should never happen, unless Willf|r makes + * a mistake. */ + KOM_ILL_MISC = 25, /* Illegal misc field. + err_stat holds field no */ + + KOM_ILLEGAL_INFO_TYPE = 26, /* Info_type parameter was illegal. This + means that there is a bug in the client. */ + KOM_ALREADY_RECIPIENT = 27, /* Already recipient to this text. */ + KOM_ALREADY_COMMENT = 28, /* Already comment to this text. */ + KOM_ALREADY_FOOTNOTE = 29, /* Already footnote to this text. */ + KOM_NOT_RECIPIENT = 30, /* Not recipient */ + KOM_NOT_COMMENT = 31, /* Not comment to this text. */ + KOM_NOT_FOOTNOTE = 32, /* Not footnote to this text. */ + KOM_RECIPIENT_LIMIT = 33, /* Too many recipients */ + KOM_COMM_LIMIT = 34, /* Too many comments */ + KOM_FOOT_LIMIT = 35, /* Too many footnotes */ + KOM_MARK_LIMIT = 36, /* Too many marks. */ + KOM_NOT_AUTHOR = 37, /* Only the author may add footnotes or + delete texts. */ + + + KOM_NO_CONNECT = 38, /* Can't connect to specified server */ + KOM_OUT_OF_MEMORY = 39, /* Couldn't get memory for result */ + KOM_SERVER_IS_CRAZY = 40, /* Client can't understand server */ + KOM_CLIENT_IS_CRAZY = 41, /* Client thinks that server says it can't + * understand client. */ + KOM_UNDEF_SESSION = 42, /* No such session exists. */ + not_used /* Det {r jobbigt att flytta kommatecknet hela + tiden... :-) /ceder */ +} Kom_err; + + +extern Kom_err kom_errno; + + +extern u_long err_stat; /* Additional information about the error */ + +/* + * print a short description of the error to stdout + */ + +void +kom_perror(void); + + +#endif /* _KOM_ERRNO_ALREADY_INCLUDED__ */ diff --git a/src/include/kom-types.h b/src/include/kom-types.h new file mode 100644 index 0000000000000000000000000000000000000000..9b41a07e7226fc37c9bf878c3902effa91c29799 --- /dev/null +++ b/src/include/kom-types.h @@ -0,0 +1,533 @@ +/* + * KOM-types.h -- Types used by both server and client of LysKOM + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + + +#ifndef KOM_TYPES_H_ALREADY_INCLUDED__ + +#define KOM_TYPES_H_ALREADY_INCLUDED__ + +#ifndef SERVER +# ifndef CLIENT +# error must define SERVER or CLIENT +# endif +#else +# ifdef CLIENT +# error must not define both SERVER and CLIENT +# endif +#endif /* !SERVER */ + +#include <sys/types.h> +#include <limits.h> +#include <time.h> + +#include <s-string.h> +#include "misc-types.h" + + +typedef u_short Pers_no; +typedef u_short Conf_no; +typedef u_long Text_no; +typedef u_long Local_text_no; +typedef u_long Session_no; + +#define MAX_PERS_NO ((Pers_no) USHRT_MAX) +#define MAX_CONF_NO ((Conf_no) USHRT_MAX) +#define MAX_TEXT_NO ((Text_no) ULONG_MAX) +#define MAX_LOCAL_TEXT_NO ((Local_text_no) ULONG_MAX) + + + +#ifdef SERVER + #define PASSWD_LEN 64 + typedef char Password[PASSWD_LEN]; + typedef off_t Text_index; + typedef time_t Time; +# define NULL_TIME_i ((Time) 0) + +#else /* CLIENT */ + typedef struct tm Time; +# define NULL_TIME_i ((Time) { 0 }) + +#endif + + + +/* + * The privilige bits: says what priviliges a person has. E g + * if he is allowed to read texts he normally shouldn't be allowed + * to read. See file doc/security-levels.txt + */ +typedef struct { + u_int wheel : 1; + u_int admin : 1; + u_int statistic : 1; + u_int create_pers: 1; + u_int create_conf: 1; + u_int change_name: 1; + u_int flg7 : 1; /* For future use. */ + u_int flg8 : 1; + u_int flg9 : 1; + u_int flg10 : 1; + u_int flg11 : 1; + u_int flg12 : 1; + u_int flg13 : 1; + u_int flg14 : 1; + u_int flg15 : 1; + u_int flg16 : 1; +} Priv_bits; + +#ifdef SERVER +# define DEFAULT_PRIV_BITS_i ((Priv_bits) \ + { 0, 0, 0, ANYONE_CAN_CREATE_NEW_PERSONS, \ + ANYONE_CAN_CREATE_NEW_CONFS, \ + DEFAULT_CHANGE_NAME, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0 \ + }) +#else +# define DEFAULT_PRIV_BITS_i ((Priv_bits) \ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0 \ + }) +#endif +extern const Priv_bits DEFAULT_PRIV_BITS; + + + +/* + * Flags in the Person struct. + */ +typedef struct { + u_int unread_is_secret : 1;/* FALSE if everyone is allowed to ask how */ + /* many unread texts you have. */ + u_int flg2 : 1; + u_int flg3 : 1; + u_int flg4 : 1; + u_int flg5 : 1; + u_int flg6 : 1; + u_int flg7 : 1; + u_int flg8 : 1; +} Personal_flags; + +#define DEFAULT_PERSONAL_FLAGS_i ((Personal_flags) \ + { 0, 0, 0, 0, 0, 0, 0, 0 }) +extern const Personal_flags DEFAULT_PERSONAL_FLAGS; + + + +/* See file doc/misc_items */ +typedef enum { recpt = 0, /* 0 Recipient (conference) */ + cc_recpt = 1, /* 1 Carbon Copy recipient (extra kopia) */ +#if 0 + ..._recpt =10, /* 10 ...recipient (F|r k{nnedom) */ +/* Vad ska det heta p} engelska? */ +/* Please let this be a comment otherwise etags voids this file. */ +#endif + comm_to = 2, /* 2 Comment to (text) */ + comm_in = 3, /* 3 Commented in (text) */ + footn_to = 4, /* 4 This is a footnote to (text) */ + footn_in = 5, /* 5 Footnote to this text in (text) */ + + + loc_no = 6, /* 6 Sequence number within conference */ + rec_time = 7, /* 7 Received at (time) */ + sent_by = 8, /* 8 Sent by (person) */ + sent_at = 9 /* 9 Sent at (time) */ +} Info_type; + +typedef union { + Conf_no recipient; + Conf_no cc_recipient; + Local_text_no local_no; + Time received_at; + Text_no comment_to; + Text_no commented_in; + Text_no footnote_to; + Text_no footnoted_in; + Pers_no sender; + Time sent_at; +} Info_datum; + + +/* This struct contains miscellaneous information about a text. */ +typedef struct { + Info_type type; + Info_datum datum; +} Misc_info; + + +/* Fields of this type is supposed to tell the garbage collector + * which texts it should remove first. + */ +typedef u_long Garb_nice; + + +/* Struct for text status */ +typedef struct { + Time creation_time; +#ifdef SERVER + long file_pos; /* Start of the text in the text file. */ +#endif + Pers_no author; + u_short no_of_lines; + String_size no_of_chars; + u_short no_of_marks; /* Antal markeringar */ + u_short no_of_misc; /* Recipients, times, comments, ... */ + Misc_info * misc_items; /* List of miscellaneous info. */ +} Text_stat; + +#ifdef SERVER +#define EMPTY_TEXT_STAT_i ((Text_stat) \ + { NULL_TIME_i, 0, 0, 0, 0, 0, 0, NULL }) +#else +#define EMPTY_TEXT_STAT_i ((Text_stat) \ + { NULL_TIME_i, 0, 0, 0, 0, 0, NULL }) +#endif + +extern const Text_stat EMPTY_TEXT_STAT; + + + +typedef struct { + u_int rd_prot : 1; /* !(Can anyone become a member?) */ + u_int original : 1; /* Comments forbidden? */ + u_int secret : 1; /* Secret conference? */ + /* Note: if a letterbox is secret it + * will be very hard for that person + * to log in, since he can't map his + * name to a pers_no. He must either + * know his pers_no, or have another + * identity which is his supervisor. + */ + u_int letter_box : 1; /* Is this a letter box? */ +} Conf_type; + +#define NULL_CONF_TYPE_i ((Conf_type) { 0, 0, 0, 0 }) +extern const Conf_type NULL_CONF_TYPE; + + + +typedef struct { + Pers_no member; +} Member; + + + +/* Struct for marks */ +typedef struct { + Text_no text_no; + u_char mark_type; /* It's up to the clients to decide the + meaning of this field. */ +} Mark; + + + +/* Information about a person's membership in a conference */ +typedef struct { + Conf_no conf_no; + u_char priority; /* Interrupt priority */ + Time last_time_read; /* Updated every time a text in this + conf. is marked as read. */ + Local_text_no last_text_read; /* All texts before and inclusive this + are read */ + u_short no_of_read; + Local_text_no * read_texts; /* Texts after last_text_read. Sorted + in ascending order */ +} Membership; + +#define EMPTY_MEMBERSHIP_i ((Membership) \ + { 0, 0, NULL_TIME_i, 0, 0, NULL }) +extern const Membership EMPTY_MEMBERSHIP; + + + +/* Some structs to handle variable-sized arrays. */ + +typedef struct { + u_short no_of_marks; + Mark * marks; /* Pointer to an array of marks. */ +} Mark_list; + +#define EMPTY_MARK_LIST_i ((Mark_list) { 0, NULL }) +extern const Mark_list EMPTY_MARK_LIST; + + +typedef struct { + u_short no_of_confs; + Conf_no *conf_nos; +} Conf_no_list; + +#define EMPTY_CONF_NO_LIST_i ((Conf_no_list) { 0, NULL }) +extern const Conf_no_list EMPTY_CONF_NO_LIST; + + +typedef struct { + u_short no_of_members; + Member * members; +} Member_list; + +#define EMPTY_MEMBER_LIST_i ((Member_list) { 0, NULL }) +extern const Member_list EMPTY_MEMBER_LIST; + + + +typedef struct { + Local_text_no first_local_no; + u_long no_of_texts; + Text_no * texts; +} Text_list; + +#define EMPTY_TEXT_LIST_i ((Text_list) { 1, 0, NULL }) +extern const Text_list EMPTY_TEXT_LIST; + + + +/* A list of conference numbers, also telling if it is a + * mailbox (i e a person) or an ordinary conference. */ +/* Delete this ugly variant as soon as possible! */ +typedef struct { + u_long no_of_conf_nos; + Conf_no * conf_nos; + Conf_type * type_of_conf; +} Conf_list_old; +/* This is the way it should look! */ +typedef struct { + Conf_no conf_no; + Conf_type type; +} Micro_conf; + +typedef struct { + u_long no_of_confs; + Micro_conf * confs; +} Conf_list; + + +#define EMPTY_CONF_LIST_OLD_i ((Conf_list_old) { 0, NULL, NULL }) +extern const Conf_list_old EMPTY_CONF_LIST_OLD; + +#define EMPTY_CONF_LIST_i ((Conf_list) { 0, NULL }) +extern const Conf_list EMPTY_CONF_LIST; + + +/* A list of person numbers */ +typedef struct { + u_long no_of_persons; + Pers_no * persons; +} Pers_list; + +#define EMPTY_PERS_LIST_i ((Pers_list) { 0, NULL }) +extern const Pers_list EMPTY_PERS_LIST; + + + +typedef struct { + u_short no_of_confs; + Membership * confs; +} Membership_list; + +#define EMPTY_MEMBERSHIP_LIST_i ((Membership_list) { 0, NULL }) +extern const Membership_list EMPTY_MEMBERSHIP_LIST; + + + +/* The Info struct */ +typedef struct { + long version; + Conf_no conf_pres_conf; /* Presentation of new confs */ + Conf_no pers_pres_conf; /* Presentation of new persons */ + Conf_no motd_conf; /* Conf that receive motds */ + Conf_no kom_news_conf; /* News about kom */ + Text_no motd_of_lyskom; /* To be displayed after login */ + /* and maybe more... */ +} Info; + + + +typedef struct { + Pers_no creator; + Time creation_time; + Text_no presentation; + Conf_no supervisor; /* Organisat|r f|r m|tet */ + Conf_no permitted_submitters; /* People who are allowed + to submit texts to this conf. + 0 -> anyone may submit. */ + Conf_no super_conf; /* Send unallowed submissions to + the super_conf. + 0 -> unallowed submissions bounce */ + Conf_type type; /* secret, rd_prot etc */ + Time last_written; /* Time of latest text in this conf. */ + Text_no msg_of_day; /* Message to be displayed when this + conf is referenced by the user. */ + Garb_nice nice; /* How long do texts in this + conf live? */ + String name; /* Name of conference */ +#ifdef CLIENT + u_short no_of_members; + Local_text_no first_local_no; + u_long no_of_texts; +#else + Member_list members; /* List of members in conf */ + Text_list texts; /* List of texts */ +#endif +} Conference; + + +#ifdef CLIENT +# define EMPTY_CONFERENCE_i ((Conference) \ + { 0, NULL_TIME_i, 0, 0, 0, 0, NULL_CONF_TYPE_i, \ + NULL_TIME_i, 0, 0, EMPTY_STRING_i, 0, 0, 0 \ + }) +#else /* SERVER */ +# define EMPTY_CONFERENCE_i ((Conference) \ + { 0, NULL_TIME_i, 0, 0, 0, 0, NULL_CONF_TYPE_i, \ + NULL_TIME_i, 0, 0, EMPTY_STRING_i, \ + EMPTY_MEMBER_LIST_i, EMPTY_TEXT_LIST_i \ + }) +#endif /* SERVER */ +extern const Conference EMPTY_CONFERENCE; + + +#ifdef SERVER +typedef struct { + String name; /* Name of conference */ + Conf_type type; /* secret, rd_prot etc */ + Local_text_no highest_local_no; /* highest local text no */ + Garb_nice nice; /* Number of days to live */ +} Small_conf; + +#define EMPTY_SMALL_CONF_i ((Small_conf){EMPTY_STRING_i, NULL_CONF_TYPE_i, \ + 0, 0}); + +extern const Small_conf EMPTY_SMALL_CONF; +#endif + + +/* Struct for persons */ +typedef struct { + Text_no user_area; /* Misc info the clients might want to + store. 0 = not used. */ + Priv_bits privileges; + Personal_flags flags; + Time last_login; /* Or logout */ + u_long total_time_present; /* Number of seconds. */ + u_long sessions; /* Number of sessions */ + u_long created_lines; /* No. of created lines (statistics) */ + u_long created_bytes; /* No. of created bytes (statistics) */ + u_long read_texts; /* No. of read texts (statistics) */ + u_long no_of_text_fetches; /* (statistics) */ + u_short created_persons; /* (statistics) */ + u_short created_confs; /* (statistics) */ + String username; /* User-name & hostname */ +#ifdef CLIENT + Local_text_no first_created_text; /* The first text that still + * exists. */ + u_long no_of_created_texts; + u_short no_of_marks; /* This many marked texts */ + u_short no_of_confs; /* Member in this many confs */ +#else /* SERVER */ + Text_list created_texts; + Mark_list marks; /* List of marked texts */ + Membership_list conferences; /* List of conferences the person is + * a member in. */ + Password pwd; /* Encrypted password */ +#endif +} Person; + +#ifdef SERVER +# define EMPTY_PERSON_i ((Person) \ + { 0, DEFAULT_PRIV_BITS_i, \ + DEFAULT_PERSONAL_FLAGS_i, NULL_TIME_i, 0, 0, \ + 0, 0, 0, 0, 0, 0, EMPTY_STRING_i, \ + EMPTY_TEXT_LIST_i, EMPTY_MARK_LIST_i, \ + EMPTY_MEMBERSHIP_LIST_i, "\001password" \ + }) +#else +# define EMPTY_PERSON_i ((Person) \ + { 0, DEFAULT_PRIV_BITS_i, \ + DEFAULT_PERSONAL_FLAGS_i, NULL_TIME_i, 0, 0, \ + 0, 0, 0, 0, 0, 0, EMPTY_STRING_i, 0, 0, 0, 0 \ + }) +#endif +extern const Person EMPTY_PERSON; + + + +/* + * This struct is returned from the 'who_is_on' call. + */ +typedef struct { + Pers_no person; + String what_am_i_doing; + Conf_no working_conference; +} Who_info_old; + +typedef struct { + Pers_no person; + String what_am_i_doing; + String username; /* Userid and hostname. */ + Conf_no working_conference; + Session_no session_no; /* Serial number of connection. */ +} Who_info; + +typedef struct { + Pers_no person; + String what_am_i_doing; + String username; /* Userid and hostname. */ + Conf_no working_conference; + Session_no session; /* Serial number of connection. */ + Time connection_time; /* Not logintime. */ + u_long idle_time; /* Seconds. */ +} Session_info; + +#define EMPTY_SESSION_INFO_i ((Session_info) { 0, EMPTY_STRING_i, \ + EMPTY_STRING_i, 0, 0, \ + NULL_TIME_i, 0 }) + +extern const Session_info EMPTY_SESSION_INFO; + +#define EMPTY_WHO_INFO_OLD_i ((Who_info_old) { 0, EMPTY_STRING_i, 0 }) + +#define EMPTY_WHO_INFO_i ((Who_info) { 0, EMPTY_STRING_i, \ + EMPTY_STRING_i, 0, 0 }) + +extern const Who_info_old EMPTY_WHO_INFO_OLD; + +extern const Who_info EMPTY_WHO_INFO; + + + +typedef struct { + int no_of_persons; + Who_info_old * info; +} Who_info_list_old; + +#define EMPTY_WHO_INFO_LIST_OLD_i ((Who_info_list_old) { 0, NULL }) +extern const Who_info_list_old EMPTY_WHO_INFO_LIST_OLD; + + +typedef struct { + int no_of_persons; + Who_info * info; +} Who_info_list; + +#define EMPTY_WHO_INFO_LIST_i ((Who_info_list) { 0, NULL }) +extern const Who_info_list EMPTY_WHO_INFO_LIST; + + +#endif /* ifndef KOM_TYPES_H_ALREADY_INCLUDED__ */ diff --git a/src/include/misc-types.h b/src/include/misc-types.h new file mode 100644 index 0000000000000000000000000000000000000000..87b110ea45e7755c3976f38de65783f82668d4df --- /dev/null +++ b/src/include/misc-types.h @@ -0,0 +1,34 @@ +/* + * misc-types.h -- Miscellaneous types and constants that are useful + * in many places in LysKOM, but are not very LysKOM- + * specific. + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + */ + + +#ifndef _MISC_TYPES_ALREADY_INCLUDED__ +#define _MISC_TYPES_ALREADY_INCLUDED__ + + +typedef enum { FALSE = 0, TRUE = 1 } Bool; + +typedef enum { OK = 017, FAILURE = 17 } Success; + +#define NO_TIME ((time_t) 0) + +#endif /* _MISC_TYPES_ALREADY_INCLUDED__ */ diff --git a/src/include/server/Makefile b/src/include/server/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..51573620b14b06f5a9ea6c6df4d83e19cfc601eb --- /dev/null +++ b/src/include/server/Makefile @@ -0,0 +1,54 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR = /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +TARGET = -DCLIENT + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + + +INSTALL-HDRS = smalloc.h + +all:; + + +.PHONY : install +install: + -mkdir $(INCLUDEDIR)/server + (cd $(INCLUDEDIR)/server; $(RM) $(INSTALL-HDRS)) + cp $(INSTALL-HDRS) $(INCLUDEDIR)/server/ + +clean: + rm -vf ${OBJECTS} *~ core temp-Makefile Distfile *.o + +depend: + >dependencies + +specials:; + +include dependencies diff --git a/src/include/server/dependencies b/src/include/server/dependencies new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/include/server/smalloc.h b/src/include/server/smalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..155eb678a67ad1f2c027e8c1778b89f06f53858d --- /dev/null +++ b/src/include/server/smalloc.h @@ -0,0 +1,57 @@ +/* + * smalloc.h + * + * Contains memory allocator routines + * + */ + +/* + * The servers "general" memory handler. + */ + + +#define SMALLOC_MAGIC_ALLOC 0x12FE56A0 +#define SMALLOC_MAGIC_FREE 0xCA348E63 + +/* + * "safe" malloc. Handles the case when malloc returns NULL. + * smalloc cannot fail. + */ +extern void * +smalloc(size_t size); + + +extern void +sfree(void * ptr); /* it is legal to sfree a NULL pointer */ + +extern void * +srealloc(void * ptr, size_t size); /* Never fails. It is legal to + realloc the NULL ptr. */ + +/* + * Allocate temporary memory, which is automatically freed after this + * atomic call. + */ +void * +tmp_alloc(u_long size); + +/* + * Free all core which is allocated with tmp_alloc(). This is called from + * end_of_atomic(). + */ +void +free_tmp(void); + +/* + * Free all memory used internally in tmp_alloc(). + */ +void +free_all_tmp(void); + + +/* + * Write statistics of memory usage. + */ + +void +dump_smalloc_counts(FILE *stat_file); diff --git a/src/include/services.h b/src/include/services.h new file mode 100644 index 0000000000000000000000000000000000000000..e847d03c14d76437f68274e02d55bc237915a16d --- /dev/null +++ b/src/include/services.h @@ -0,0 +1,477 @@ +/* + * services.h -- All the services the LysKOM server makes available + * for clients. + * + * Requires kom-types.h + * + * Created by ceder 1990-03-23 + */ + + +#ifndef _SERVICES_H_ALREADY_INCLUDED__ +#define _SERVICES_H_ALREADY_INCLUDED__ + + +#if defined (CLIENT) +# if defined (SERVER) +# error Both CLIENT and SERVER defined! +# endif +# define KOM_(function) kom_ ## function +# define CONST const +#elif defined (SERVER) +# define KOM_(function) function +# define CONST +#else +# error Neither CLIENT nor SERVER defined! +#endif + + + + +/* + * Session control + */ +#ifdef CLIENT +extern Success +KOM_( open_connection (const char * server )); + +extern void +KOM_( set_storage_management (malloc_function new_malloc, + realloc_function new_realloc, + free_function new_free)); + +#endif + + +extern Success +KOM_( login (Pers_no person, + const String passwd )); + +extern Success +KOM_( logout (void)); /* can never fail */ + +/* Change Conference */ +extern Success +KOM_( pepsi (Conf_no conference )); + + +/* Change name of a person or conference. */ +extern Success +KOM_( change_name (Conf_no conf_no, + const String new_name)); + +extern Success +KOM_( change_what_i_am_doing (CONST String what_am_i_doing )); + + +/* Get info about a session */ + +extern Success +KOM_( get_session_info (Session_no session_no, + Session_info *result) ); + +/* + * Disconnect a session. You can disconnect your own session (even if + * you are not logged in) and any session where you are supervisor of + * the user that is logged in on that session. + */ +extern Success +KOM_( disconnect (Session_no session_no)); + +/* + * Returns your session number + */ +extern Success +KOM_( who_am_i (Session_no *session_no)); + + +/****************************** +* Person-related calls * +******************************/ + +/* + * Create a new person. Returns 0 if any error occured. + */ +extern Pers_no +KOM_( create_person (const String name, + const String passwd )); + + +/* Obsolete call; use get_person_stat instead. */ +extern Success +KOM_( get_person_stat_old (Pers_no person, + int mask, + Person * result )); + +extern Success +KOM_( get_person_stat (Pers_no person, + Person * result )); + + + +extern Success +KOM_( get_created_texts (Pers_no person, + Local_text_no first, + u_long no_of_texts, + Text_list * created_texts )); + +extern Success +KOM_( get_membership (Pers_no person, + u_short first, + u_short no_of_confs, + Bool want_read_texts, + Membership_list * memberships )); + + + +extern Success +KOM_( set_priv_bits (Pers_no person, + Priv_bits privileges )); + + +/* Set the password of PERSON to NEW_PWD. OLD_PWD is the password + * of the person who does the set. This is not necessarily the + * same as the one who gets it set. */ +extern Success +KOM_( set_passwd (Pers_no person, + const String old_pwd, + const String new_pwd )); + + +/* You can query for unread texts without logging in. */ +extern Success +KOM_( query_read_texts (Pers_no pers_no, + Conf_no conf_no, + Membership * result )); + + +extern Success +KOM_( get_unread_confs(Pers_no pers_no, + Conf_no_list *result)); + +extern Success +KOM_( set_user_area(Pers_no pers_no, + Text_no user_area)); + + +/**************************************** +* Conference-related calls * +****************************************/ + + +extern Conf_no +KOM_( create_conf (const String name, + Conf_type type )); + + +/* Delete a conference. Also used to delete persons. */ +extern Success +KOM_( delete_conf (Conf_no conf )); + + +/* + * Map conference name to number. Returns a list of the conferences + * that match the name NAME. Can be done without logging in. + */ +#ifdef SERVER +extern Success +KOM_( lookup_name (const String name, + Conf_list_old *result)); +#else +extern Success +KOM_( lookup_name (const String name, + Conf_list *result)); +#endif + +extern Success +KOM_( get_conf_stat_old (Conf_no conf_no, + int mask, + Conference * result )); + +extern Success +KOM_( get_conf_stat (Conf_no conf_no, + Conference * result )); + +extern Success +KOM_( get_members (Conf_no conf, + u_short first, + u_short no_of_members, + Member_list * members )); + + + +/* add_member is also used to change the priority of a conference */ +extern Success +KOM_( add_member (Conf_no conf_no, + Pers_no pers_no, + u_char priority, + u_short where )); /* Range of where is [0..] */ + + +extern Success +KOM_( sub_member (Conf_no conf_no, + Pers_no pers_no )); + + +/* + * Tell the server that I want to mark/unmark texts as read so that I + * get no_of_unread unread texts in conf_no. + */ +extern Success +KOM_( set_unread (Conf_no conf_no, + Text_no no_of_unread)); + +/* + * set_presentation and set_etc_motd also does some magic with the + * no_of_marks field in the Text_stat structure of the old and new text. + */ + +extern Success +KOM_( set_presentation (Conf_no conf_no, + Text_no text_no )); /* 0 to delete pres. */ + +extern Success +KOM_( set_etc_motd (Conf_no conf_no, + Text_no text_no )); + + +extern Success +KOM_( set_supervisor (Conf_no conf_no, + Conf_no admin )); + +extern Success +KOM_( set_permitted_submitters (Conf_no conf_no, + Conf_no perm_sub )); + +extern Success +KOM_( set_super_conf (Conf_no conf_no, + Conf_no super_conf )); + +extern Success +KOM_( set_conf_type (Conf_no conf_no, + Conf_type type )); + +extern Success +KOM_( set_garb_nice (Conf_no conf_no, + Garb_nice nice )); /* number of days */ + + + +/******************************** +* Calls to handle marks * +********************************/ + + +extern Success +KOM_( get_marks (Mark_list *result )); + + + +/* + * Will fail if the user is not allowed to read the text. + */ +extern Success +KOM_( mark_text (Text_no text, + u_char mark_type )); + + + + +/******************************* +* Calls to handle texts * +*******************************/ + + +extern Success +KOM_( get_text (Text_no text, + String_size start_char, + String_size end_char, + String * result)); + + +extern Success +KOM_( get_text_stat (Text_no text, + Text_stat *result)); + +extern Success +KOM_( mark_as_read (Conf_no conference, + int no_of_texts, + const Local_text_no * text_arr )); + + +/* Returns 0 on error */ +extern Text_no +KOM_( create_text (CONST String message, + u_short no_of_misc, + CONST Misc_info * misc )); + +extern Success +KOM_( delete_text( Text_no text_no )); + + + +extern Success +KOM_( add_recipient (Text_no text_no, + Conf_no conf_no, + Info_type type )); /* recpt or cc_recpt */ + +extern Success +KOM_( sub_recipient (Text_no text_no, + Conf_no conf_no )); + + +extern Success +KOM_( add_comment (Text_no comment, + Text_no comment_to )); + + +/* + * Make the text COMMENT to not be a comment to text COMMENT_TO + */ +extern Success +KOM_( sub_comment (Text_no comment, + Text_no comment_to )); + +extern Success +KOM_( add_footnote (Text_no footnote, + Text_no footnote_to )); + +extern Success +KOM_( sub_footnote (Text_no footnote, + Text_no parent )); + +extern Success +KOM_( get_map (Conf_no conf_no, + Local_text_no first_local_no, + u_long no_of_texts, + Text_list * result)); + + +/* + * Ask what the server thinks the time is. This + * might differ if on two different machines. + */ +#ifdef SERVER +extern Success +KOM_( get_time (time_t *time)); +#else /* CLIENT */ +extern Success +KOM_( get_time (struct tm *clock)); +#endif + + +/* + * Who is logged on now? + */ +extern Success +KOM_( who_is_on_old (Who_info_list_old * result )); + +extern Success +KOM_( who_is_on (Who_info_list * result )); + + +/* + * Return various information about the server + */ +extern Success +KOM_( get_info (Info *result )); + +/* + * Wait for asynchronous message from client, or input on any of + * the file-descriptors in opt_set. Returns FAILURE if nothing + * happened in msec milliseconds or an error occurs. (kom_errno == + * KOM_NO_ERR if the return was due to a timeout). Returns OK if + * there was an asynchronous message or input on any of the fd's in + * opt_set. + * + * Set opt_set to NULL if you don't want to wait on any other input + * than a message. + * + * To wait for a message or input on stdin the following code can be used: + * + * fd_set read_set; + * + * FD_ZERO(&read_set); + * FD_SET(fileno(stdin), &read_set); + * if ( kom_wait(read_set, 1000) == OK ) + * { + * if ( FD_ISSET(fileno(stdin), &read_set) ) + * handle_stdin_input(); + * else + * handle_asynchronous_message(); + * } + * else + * time_out(); + * + * (The handler is called from kom_wait and not handle_asynchronous_message, + * but there might be more to do afterwards since a handler cannot call + * functions that communicate with the server.) + */ +#ifdef CLIENT +extern Success +KOM_( wait (fd_set *opt_set, + int msec)); +#endif + +/* + * Privileged calls. + */ + +extern Success +KOM_( set_motd_of_lyskom (Text_no motd)); + +/* + * Set ena_level. 0 means don't use any privileges. + */ +extern Success +KOM_( enable (u_char ena_level)); + +/* + * Make LysKOM sync its files. + */ +extern Success +KOM_( sync (void) ); + +/* + * Close LysKOM. + */ +extern Success +KOM_( shutdown (int exit_val) ); + +/* + * Send a message to all clients. This is obsoleted by send_message() + * and will soon go away. + */ +extern Success +KOM_( broadcast (const String message) ); + +/* + * Send a message to a person, or all persons. If recipient == 0 all + * connections will receive the message. + */ +extern Success +KOM_( send_message (Pers_no recipient, + const String message) ); + + +/* + * Asynchronous messages. + */ +#ifdef CLIENT +void +register_new_text(void (*async_new_text)(Text_no text_no, + Text_stat text_s)); + +void +register_i_am_on(void (*async_i_am_on)(Who_info info)); + +void +register_i_am_off (void (*async_i_am_off)(Pers_no pers_no)); + +void +register_new_name(void (*async_new_name)(Conf_no conf_no, + String old_name, + String new_name)); +#endif /* CLIENT */ + +#endif /* _SERVICES_H_ALREADY_INCLUDED__ */ diff --git a/src/libraries/Makefile b/src/libraries/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d69235845cdf4cbac6e639520c369d354ac0fdde --- /dev/null +++ b/src/libraries/Makefile @@ -0,0 +1,46 @@ +# All directories that make should traverse to when doing clean etc. +# Note that client-support depends on libmisc. + +SUBDIRS = libansi libmisc libisc libcommon client-support + +all: + for i in $(SUBDIRS) ; \ + do \ + echo making all in directory $$i; \ + (cd $$i; $(MAKE) all) \ + done + + +depend: + for i in $(SUBDIRS) ; \ + do \ + echo making depend in directory $$i; \ + (cd $$i; $(MAKE) depend); \ + echo make depend in directory $$i ready.; \ + done + + +install: + for i in $(SUBDIRS) ; \ + do \ + echo making install in directory $$i; \ + (cd $$i; $(MAKE) install) \ + done + + +install-headers: + for i in $(SUBDIRS) ; \ + do \ + echo making install-headers in directory $$i; \ + (cd $$i; $(MAKE) install-headers) \ + done + + +clean: + rm -vf *~ core + for i in $(SUBDIRS); \ + do \ + echo making clean in directory $$i; \ + (cd $$i; $(MAKE) clean) \ + done + diff --git a/src/libraries/libansi/Makefile b/src/libraries/libansi/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3f63c0e258fd92db01169e73919a45c830bb8123 --- /dev/null +++ b/src/libraries/libansi/Makefile @@ -0,0 +1,67 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR = /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +TARGET = -DCLIENT + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + + +LIBNAME = libansi.a + +LIBOBJS = strerror.o + +all: $(LIBNAME) + +libmisc.a: $(LIBOBJS) + rm -f $(LIBNAME) + ar qc $(LIBNAME) $(LIBOBJS) + ranlib $(LIBNAME) + +install-headers:; + +install: $(LIBNAME) + $(RM) $(LIBDIR)/$(LIBNAME) + cp $(LIBNAME) $(LIBDIR)/$(LIBNAME) + ranlib $(LIBDIR)/$(LIBNAME) + + +clean: + rm -vf ${LIBOBJS} *~ core temp-Makefile Distfile *.o + + +# Recreate the Makefile +include $(SCRIPTDIR)/Parallell-depend.make + + +tags: + etags -t *.[hc] + +specials:; + +include dependencies diff --git a/src/libraries/libansi/README b/src/libraries/libansi/README new file mode 100644 index 0000000000000000000000000000000000000000..e721d6dd83cf552b0ba584869d15fb17f1883c8f --- /dev/null +++ b/src/libraries/libansi/README @@ -0,0 +1,5 @@ +Detta {r t{nkt att bli ett bibliotek med divers rutiner som beh|vs +f|r de stackare utan ANSI bibliotek.. (Alla n{stan). + +/pen + diff --git a/src/libraries/libansi/config.h b/src/libraries/libansi/config.h new file mode 100644 index 0000000000000000000000000000000000000000..9fe0eaccb0b468492fcd545ace08e347f9109505 --- /dev/null +++ b/src/libraries/libansi/config.h @@ -0,0 +1,8 @@ +/* +** config.h +** +** System: SunOS 4.1.1 +*/ + + +/* #define HAVE_STRERROR /* */ diff --git a/src/libraries/libansi/dependencies b/src/libraries/libansi/dependencies new file mode 100644 index 0000000000000000000000000000000000000000..00b32730b77072831534c7517dc2c393a9df1e19 --- /dev/null +++ b/src/libraries/libansi/dependencies @@ -0,0 +1 @@ +strerror.o : strerror.c config.h diff --git a/src/libraries/libansi/libansi.a b/src/libraries/libansi/libansi.a new file mode 100644 index 0000000000000000000000000000000000000000..da20a4f3e62e290cd2381b772fd4d11db21625e9 Binary files /dev/null and b/src/libraries/libansi/libansi.a differ diff --git a/src/libraries/libansi/strerror.c b/src/libraries/libansi/strerror.c new file mode 100644 index 0000000000000000000000000000000000000000..dfbc8776f815ee16d81999340dde1c6f371b8c5b --- /dev/null +++ b/src/libraries/libansi/strerror.c @@ -0,0 +1,23 @@ +/* +** strerror.c +*/ +#include "config.h" + +#ifndef HAVE_STRERROR + +extern int sys_nerr; +extern char *sys_errlist[]; + +char *strerror(int eno) +{ + static char buf[20]; + + if (eno < 0 || eno >= sys_nerr) + { + sprintf(buf, "Error %d", eno); + return buf; + } + else + return sys_errlist[eno]; +} +#endif diff --git a/src/libraries/libcommon/ChangeLog b/src/libraries/libcommon/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..f17c43a9314993368574937ab27df9bc3d0545c5 --- /dev/null +++ b/src/libraries/libcommon/ChangeLog @@ -0,0 +1,15 @@ +Sat Jul 6 06:15:40 1991 Per Cederqvist (ceder at lysator) + + * Fixade makefilen s} att den kan generera b}de liblyskom-server.a + och liblyskom-client.a. (Den ena kompilerad med SERVER + definierad, den andra med CLIENT definierad). "make depend" + kr{ver i nul{get manuella efterjusteringar. + + * misc-parser.h: "time_t" bytt mot "Time" (som {r "struct tm" i + klienten och "time_t" i servern). + + * [ndrade "typedef struct {...} Matching_info" till "typedef + struct matching_info {...} Matching_info". + + * parser.h: s-collat-tables.h -> s-collat-tabs.h. + diff --git a/src/libraries/libcommon/Makefile b/src/libraries/libcommon/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ea6bd2331a8dbcb10c7cda79ceaa949efb321ebd --- /dev/null +++ b/src/libraries/libcommon/Makefile @@ -0,0 +1,98 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR = /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +TARGET = -DCLIENT + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + + +LIBOBJS = kom-errno.o misc-parser.o parser.o +HDRS = misc-parser.h parser.h +LIBRARIES = liblyskom-server.a liblyskom-client.a + +all: $(LIBRARIES) + +client-dir: + mkdir client-dir + ln -s `echo $(LIBOBJS) $(HDRS) dependencies| tr ' ' '\012' | \ + sed 's/.o$$/.c/' | sed 's:^:\.\./:' ` client-dir/ + +server-dir: + mkdir server-dir + ln -s `echo $(LIBOBJS) $(HDRS) dependencies| tr ' ' '\012' | \ + sed 's/.o$$/.c/' | sed 's:^:\.\./:' ` server-dir/ + +.PHONY: liblyskom-server.a +liblyskom-server.a: server-dir + (cd server-dir; make -f ../Makefile ../$@ TARGET=-DSERVER) + ranlib $@ + + +../liblyskom-server.a: $(LIBOBJS) + $(AR) $(ARFLAGS) $@ $? + +.PHONY: liblyskom-client.a +liblyskom-client.a: client-dir + (cd client-dir; make -f ../Makefile ../$@ TARGET=-DCLIENT) + ranlib $@ + + +../liblyskom-client.a: $(LIBOBJS) + $(AR) $(ARFLAGS) $@ $? + + +clean: + $(RM) -r *.o core Distfile *~ client-dir server-dir $(LIBRARIES) + +install: all install-headers + (cd $(LIBDIR); $(RM) $(LIBRARIES)) + cp $(LIBRARIES) $(LIBDIR) + (cd $(LIBDIR); ranlib -t $(LIBRARIES)) + +.PHONY: install-headers +install-headers: + (cd $(INCLUDEDIR); $(RM) $(HDRS)) + cp $(HDRS) $(INCLUDEDIR) + +tags: + etags -t $(INCLUDEDIR)/*.h *.[hc] + +#rdist: clean +# echo "(/usr/local/src/2kom/common) -> (nanny.lysator.liu.se)" >Distfile +# echo "install;" >>Distfile +# rdist + +# Recreate the Makefile from Makefile + +include $(SCRIPTDIR)/Parallell-depend.make + +specials:; + +include dependencies diff --git a/src/libraries/libcommon/README b/src/libraries/libcommon/README new file mode 100644 index 0000000000000000000000000000000000000000..3f695f0c4329e9ff06bf83757ade10d6d5428cd8 --- /dev/null +++ b/src/libraries/libcommon/README @@ -0,0 +1,2 @@ +All utveckling i detta bibliotek sker p} LLL. +H{r ligger saker som anv{nds b}de i servern och tty-klienten. diff --git a/src/libraries/libcommon/dependencies b/src/libraries/libcommon/dependencies new file mode 100644 index 0000000000000000000000000000000000000000..a88cc83be419c0c8c24983011a73bb0c9f1065db --- /dev/null +++ b/src/libraries/libcommon/dependencies @@ -0,0 +1,6 @@ +kom-errno.o : kom-errno.c /users/ceder/gurka/lyskom/include/ansi/stdio.h \ + /users/ceder/gurka/lyskom/include/config.h \ + /users/ceder/gurka/lyskom/include/kom-errno.h \ + /usr/gnu/lib/gcc-include/sys/types.h /usr/include/sys/types.h \ + /usr/gnu/lib/gcc-include/sys/stdtypes.h /usr/include/sys/stdtypes.h \ + /usr/include/sys/sysmacros.h diff --git a/src/libraries/libcommon/kom-errno.c b/src/libraries/libcommon/kom-errno.c new file mode 100644 index 0000000000000000000000000000000000000000..16d9a2954d3585d76ab1d460dd3edf607ce0540b --- /dev/null +++ b/src/libraries/libcommon/kom-errno.c @@ -0,0 +1,175 @@ +/* + * kom_errno.c + * + * Created by ceder 1990-05-13 + * + */ + + +#include <stdio.h> + +#include <config.h> + +#include <kom-errno.h> + + +Kom_err kom_errno; + +/* Additional information about the error */ +u_long err_stat; + +/* Note that kom_errout is defined in config.h */ + +void +kom_perror(void) +{ + switch (kom_errno) + { + case KOM_NO_ERROR: + fprintf (kom_errout, "Why am I called? There was no error!\n"); + break; + + case KOM_NOT_IMPL: + fprintf(kom_errout, "Not implemented yet\n"); + break; + + case KOM_PWD: + fprintf(kom_errout, "Wrong/illegal password\n"); + break; + + case KOM_LOGIN: + fprintf(kom_errout, "Not logged in.\n"); + break; + + case KOM_LOGIN_DISALLOWED: + fprintf(kom_errout, "System is in 'singel-user mode'\n"); + break; + + case KOM_CONF_ZERO: + fprintf(kom_errout, "Attempt to use conference number 0.\n"); + break; + + case KOM_UNDEF_CONF: + fprintf(kom_errout, "Undefined or secret conference\n"); + break; + + case KOM_UNDEF_PERS: + fprintf(kom_errout, "Undefined or secret person\n"); + break; + + case KOM_ACCESS: + fprintf(kom_errout, "No 'read/write permission'\n"); + break; + + case KOM_SECRET_PUBLIC: + fprintf(kom_errout, "Cannot be secret and !rd_prot\n"); + break; + + case KOM_LETTER_BOX: + fprintf(kom_errout, "Cannot change letter_box flag\n"); + break; + + case KOM_PERM: + fprintf(kom_errout, "No permission\n"); + break; + + case KOM_NOT_MEMBER: + fprintf(kom_errout, "Not member in conf\n"); + break; + + case KOM_NO_SUCH_TEXT: + fprintf(kom_errout, "No such global text as %ld or no access\n", + err_stat); + break; + + case KOM_NO_SUCH_LOCAL_TEXT: + fprintf(kom_errout, "No such local text as %ld\n", err_stat); + break; + + case KOM_INDEX_OUT_OF_RANGE: + fprintf(kom_errout, "Index out of range\n"); + break; + + case KOM_BAD_NAME: + fprintf(kom_errout, "To short/long or contains illegal chars\n"); + break; + + case KOM_CONF_EXISTS: + fprintf(kom_errout, "Already exists\n"); + break; + + case KOM_PERS_EXISTS: + fprintf(kom_errout, "Already exists\n"); + break; + + case KOM_LDB_ERR: + fprintf(kom_errout, "LDB_err\n"); + break; + + case KOM_ILL_MISC: + fprintf(kom_errout, "Illegal misc field at %ld.\n", err_stat); + break; + + case KOM_ILLEGAL_INFO_TYPE: + fprintf(kom_errout, "Info_type parameter illegal. Client is buggy.\n"); + break; + + case KOM_ALREADY_RECIPIENT: + fprintf(kom_errout, "Already recipient to this text.\n"); + break; + + case KOM_NOT_RECIPIENT: + fprintf(kom_errout, "Not recipient.\n"); + break; + + case KOM_RECIPIENT_LIMIT: + fprintf(kom_errout, "Too many recipients.\n"); + break; + + case KOM_COMM_LIMIT: + fprintf(kom_errout, "Too many comments.\n"); + break; + + case KOM_FOOT_LIMIT: + fprintf(kom_errout, "Too many footnotes.\n"); + break; + + case KOM_NOT_AUTHOR: + fprintf(kom_errout, "Only the author may add footnotes.\n"); + break; + + case KOM_OBSOLETE: + fprintf (kom_errout, "Servern {r inte kompatibel med mig.\n"); + break; + + case KOM_LONG_STR: + fprintf (kom_errout, "F|r l}ng str{ng.\n"); + break; + + case KOM_NO_CONNECT: + fprintf (kom_errout, "Kan ej f} kontakt med servern.\n"); + break; + + case KOM_OUT_OF_MEMORY: + fprintf (kom_errout, "Dumma Emacs! Fattar du inte att du inte ska " + "bryta en\nrad inuti en str{ng bara f|r att man anv{nder " + "} och {???\n"); + break; + + case KOM_SERVER_IS_CRAZY: + fprintf (kom_errout, "Hmm, jag tror servern har b|rjat tala i " + "tungom}l...\n"); + break; + + case KOM_CLIENT_IS_CRAZY: + fprintf (kom_errout, "Hoppschan. Jag har vischt b|rjat schluddra.\n"); + break; + +#ifndef COMPILE_CHECKS + default: + fprintf(kom_errout, "Unknown error %d\n", kom_errno); + break; +#endif + } +} + diff --git a/src/libraries/libcommon/misc-parser.c b/src/libraries/libcommon/misc-parser.c new file mode 100644 index 0000000000000000000000000000000000000000..e32561b500373c0c374c0e6a4e7024b73b061008 --- /dev/null +++ b/src/libraries/libcommon/misc-parser.c @@ -0,0 +1,182 @@ +/* + * misc-parser.c + * Parse a list of misc-items for LysKOM texts. + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + * + * Any opinions expressed in this code are the author's PERSONAL opinions, + * and does NOT, repeat NOT, represent any official standpoint of Lysator, + * even if so stated. + */ + + + +#include "misc-parser.h" + +#define EXPORT + + +/* + * Return TRUE if the next misc-item exist, and it is of type + * MTYPE, FALSE otherwise. Can only be used within the function + * parse_next_misc(). + */ +#define NEXT_IS(mtype) \ + (*info < stop_pointer && (*info)->type == (mtype)) + + +#define BARF { result.type = m_error; return result; } + + +/* + * Parse out a "group" of misc-items from a list of them pointed + * to by *INFO. *STOP_POINTER must point to the item directly + * after the last in the list. **INFO will be incremented to + * point to the item after the recently parsed out group. The + * return value will have the TYPE field set to 'm_end_of_list' + * when the end of the list has been reached. + */ +EXPORT Misc_info_group +parse_next_misc (const Misc_info ** info, + const Misc_info * stop_pointer) + +{ + Misc_info_group result; + + + + /* Clear the 'result' struct */ + result.type = m_error; + result.recipient = 0; + result.cc_recipient = 0; + result.local_no = 0; + result.is_received = FALSE; + result.comment_to = 0; + result.commented_in = 0; + result.footnote_to = 0; + result.footnoted_in = 0; + result.sender = 0; + result.is_sent = 0; + + + if (*info >= stop_pointer) + { + result.type = m_end_of_list; + return result; + } + + + /* Now, do the real work... */ + switch ((*info)->type) + { + case recpt: /* These two are so similar that they can */ + case cc_recpt: /* Be handled in the same clause */ + if ((*info)->type == recpt) + { + result.type = m_recpt; + result.recipient = (*(*info)++).datum.recipient; + } + else + { + result.type = m_cc_recpt; + result.cc_recipient = (*(*info)++).datum.cc_recipient; + } + + /* There should follow a 'Local no', but check nevertheless */ + if (! NEXT_IS (loc_no)) + { BARF } + else + result.local_no = (*(*info)++).datum.local_no; + + if (NEXT_IS (rec_time)) + { + result.is_received = TRUE; + result.received_at = (*(*info)++).datum.received_at; + } + + if (NEXT_IS (sent_by)) + { + result.sender = (*(*info)++).datum.sender; + /* There _should_ be a 'sent_at' here... */ + if (! NEXT_IS (sent_at)) + { BARF } + /* Let the following if clause insert the 'sent_at' data. */ + } + if (NEXT_IS (sent_at)) + { + result.is_sent = TRUE; + result.sent_at = (*(*info)++).datum.sent_at; + } + + break; + + + case comm_to: + result.type = m_comm_to; + result.comment_to = (*(*info)++).datum.comment_to; + + if (NEXT_IS (sent_by)) + { + result.sender = (*(*info)++).datum.sender; + /* There _should_ be a 'sent_at' here. */ + if (! NEXT_IS (sent_at)) + { BARF } + /* Let the following if clause insert the 'sent_at' data. */ + } + if (NEXT_IS (sent_at)) + { + result.is_sent = TRUE; + result.sent_at = (*(*info)++).datum.sent_at; + } + + break; + + + case footn_to: + result.type = m_footn_to; + result.footnote_to = (*(*info)++).datum.footnote_to; + + if (NEXT_IS (sent_at)) + { + result.is_sent = TRUE; + result.sent_at = (*(*info)++).datum.sent_at; + } + + break; + + + case comm_in: + result.type = m_comm_in; + result.commented_in = (*(*info)++).datum.commented_in; + break; + + + case footn_in: + result.type = m_footn_in; + result.footnoted_in = (*(*info)++).datum.footnoted_in; + break; + + +#ifndef COMPILE_CHECKS + default: + result.type = m_error; + break; +#endif + } + + return result; +} diff --git a/src/libraries/libcommon/misc-parser.h b/src/libraries/libcommon/misc-parser.h new file mode 100644 index 0000000000000000000000000000000000000000..f5b1b18796e4e71d9482d88f6ffb9c20c711d949 --- /dev/null +++ b/src/libraries/libcommon/misc-parser.h @@ -0,0 +1,76 @@ +/* + * misc-parser.h + * Parse a list of "misc-item":s for a text in LysKOM + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + + +#include <kom-types.h> + + + +typedef enum { + m_recpt, + m_cc_recpt, + m_comm_to, + m_comm_in, + m_footn_to, + m_footn_in, + m_end_of_list, /* End of list reached */ + m_error /* Bad misc-items found */ +} Misc_struct_type; + + +typedef struct { + Misc_struct_type type; + Conf_no recipient; + Conf_no cc_recipient; + Local_text_no local_no; + Time received_at; + Text_no comment_to; + Text_no commented_in; + Text_no footnote_to; + Text_no footnoted_in; + Pers_no sender; + Time sent_at; + Bool is_received; + Bool is_sent; +} Misc_info_group; + + + +#define is_received(mstruct) ((mstruct).is_received != FALSE) +#define is_sent_by(mstruct) ((mstruct).sender != 0) +#define is_sent(mstruct) ((mstruct).is_sent != FALSE) + + +/* + * Parse out a "group" of misc-items from a list of them pointed + * to by *INFO. *STOP_POINTER must point to the item directly + * after the last in the list. **INFO will be incremented to + * point to the item after the recently parsed out group. The + * return value will have the TYPE field set to 'm_end_of_list' + * when the end of the list has been reached. + * + * If the has a bad format, the TYPE field will be 'm_error', + * and **INFO_POINTER will point to the item before the bad (or + * missing) item. + */ +extern Misc_info_group +parse_next_misc (const Misc_info ** info_pointer, + const Misc_info * stop_pointer); diff --git a/src/libraries/libcommon/parser.c b/src/libraries/libcommon/parser.c new file mode 100644 index 0000000000000000000000000000000000000000..fd445f717c840aa2c5b723323bd1c10ecf488cd0 --- /dev/null +++ b/src/libraries/libcommon/parser.c @@ -0,0 +1,418 @@ +/* + * client/parser.c -- Routines to parse commands + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + * + * Any opinions expressed in this code are the author's PERSONAL opinions, + * and does NOT, repeat NOT, represent any official standpoint of Lysator, + * even if so stated. + */ + + + +#include <stddef.h> + +#include <s-string.h> +#include <s-collat-tabs.h> + +#include <misc-types.h> + +#include "parser.h" + + +#define EXPORT /* To emphasize export of objects */ +#define PRIVATE static + + +#if defined (SERVER) +# include <server/smalloc.h> +# define MALLOC smalloc +# define REALLOC srealloc +# define FREE sfree +#elif defined (CLIENT) +# include <zmalloc.h> +# define MALLOC zmalloc +# define REALLOC zrealloc +# define FREE zfree +#else +# include <malloc.h> +# define MALLOC malloc +# define REALLOC realloc +# define FREE free +#endif + + + +/* + * Remove paranthesized "expressions" from the string STR. + * E g if STR is "Foo (Bar (vfslck)) Gazonk", then it is reduced + * to "Foo _ Gazonk", where '_' is the character in SEPARATOR. + * Superflous close paranthesis are disregarded. + */ +EXPORT void +remove_parenthesis (String * str, + char blanker) + +{ + String_size i; /* Index in loop */ + int nesting_depth; + + + /* Match parantheses. Remove text inside parantheses. */ + nesting_depth = 0; + for ( i = 0 ; i < s_strlen(*str) ; i++ ) + { + if (str->string[i] == '(') + nesting_depth++; + + if (str->string[i] == ')') + { + nesting_depth--; + str->string[i] = blanker; /* Don't forget that... */ + if (nesting_depth < 0) + nesting_depth = 0; + } + + if (nesting_depth > 0) + str->string[i] = blanker; + } + + return; +} + + + + +/* + * Convert a String to a list of tokens (words). This list is + * easier to parse than a string (since the string would have to + * be tokenized first anyway). The last entry is EMPTY_STRING. + * Returns NULL if any error occured (couldn't allocate memory). + */ +EXPORT Parse_token * +tokenize (const String source, + const String separators) + +{ + Parse_token * tokens = NULL; + Parse_token * temp_list; /* Temporary */ + String work_string = EMPTY_STRING; + String a_token; + String a_temp_token; /* More temporaries... */ + int no_of_tokens; + int list_size; + String_size pos_in_string; + const int chunk_size = 10; + + + + /* Copy string to working area */ + if (s_strcpy(&work_string, source) == FAILURE) + { + /* Couldn't allocate space for temporary string. */ + return NULL; + } + + remove_parenthesis (&work_string, separators.string[0]); + + no_of_tokens = 0; + list_size = 0; + pos_in_string = 0; + + while ( ! s_empty(a_token + = s_strtok (work_string, &pos_in_string, + separators))) + { + /* Make the token point into the original source string + * instead of the working string */ + a_temp_token = s_fsubstr (source, + pos_in_string - s_strlen (a_token), + pos_in_string - 1); +#if 0 +// * /* Get a real copy of the word */ +// * a_temp_token = EMPTY_STRING; +// * if (s_strcpy(&a_temp_token, a_token) == FAILURE) +// * { +// * /* Grumble... */ +// * free_tokens (tokens); +// * s_clear(&work_string); +// * return NULL; +// * } +#endif + + /* Is the allocated list large enough? */ + if (no_of_tokens++ >= list_size) + { + /* No, allocate more */ + temp_list = REALLOC (tokens, (list_size += chunk_size) + * sizeof(Parse_token)); + if (temp_list == NULL) + { + /* Sigh. Out of memory. */ + free_tokens (tokens); + s_clear (&work_string); + return NULL; + } + else + { + /* OK, we got what we asked for */ + tokens = temp_list; + } + } + + /* Insert the new token in the list */ + tokens [no_of_tokens-1].word = a_temp_token; + tokens [no_of_tokens-1].start_in_string = + pos_in_string - s_strlen(a_temp_token); + } + + s_clear (&work_string); + + /* Is there room in the list for the 'stop' element? */ + if (list_size <= no_of_tokens) + { + /* No, get some more memory */ + temp_list = REALLOC (tokens, (++list_size) * sizeof(Parse_token)); + if (temp_list == NULL) + { + /* Sigh. Out of memory. */ + free_tokens (tokens); + return NULL; + } + else + { + /* OK, we got what we asked for */ + tokens = temp_list; + } + } + + /* OK, insert the 'stop' element. */ + tokens [no_of_tokens].word = EMPTY_STRING; + tokens [no_of_tokens].start_in_string = END_OF_STRING; + + return tokens; +} + + + + +/* + * Count the number of tokens (words) in TOKEN_LIST. Used to + * set the NUMBER_OF_WORDS field in a 'Matching_info' object. + */ +extern int +count_words (const Parse_token * token_list) + +{ + int no_of_words; + + no_of_words = 0; + while (! s_empty(token_list++ -> word)) + no_of_words++; + + return no_of_words; +} + + + + +/* + * Free the list of tokens (// and the strings they are pointing to //). + * Free:ing NULL is a no-op. + */ +EXPORT void +free_tokens (Parse_token * token_list) + +{ + if (token_list != NULL) + { + FREE (token_list); + } +} + + + + +/* + * Returns the number of the first word of SOURCE that does + * not match PATTERN. A word "foo" in SOURCE matches "foobar" + * in PATTERN, but not vice versa. + */ +EXPORT int +match (Parse_token * source, + Parse_token * pattern, + char collat_tab [ COLLAT_TAB_SIZE ] ) + +{ + int word_no; + + word_no = 0; + while ( (! s_streq (pattern[word_no].word, EMPTY_STRING)) + && (! s_streq (source[word_no].word, EMPTY_STRING)) + && (s_usr_strhead (source[word_no].word, + pattern[word_no].word, + collat_tab))) + { + word_no++; + } + + return word_no; +} + + + + +/* + * Searches for a matching string in the table 'match_table'. + * Some weird pattern matching is done. + * parse().no_of_matches is -1 if an error occured (out of + * memory). + * + * What? You want a description of how it matches? Forget it! BUG! + * Try for yourself, and you'll find out! + */ + +EXPORT Parse_info +parse (String source_string, + Matching_info * match_table, + Bool allow_trailing_words, + Bool number_of_words_must_match, + String separators, + char collat_tab [ COLLAT_TAB_SIZE ] ) + +{ + Parse_info answer; + int * temp_indexes; + int index; + int size_of_index_list; + Parse_token * source_words; + int no_of_source_words; + int first_non_matching; + int best_match; + int highest_priority; + + const int chunk_size = 20; + + + + source_words = tokenize(source_string, separators); + if (source_words == NULL) + { + answer.no_of_matches = -1; + return answer; + } + + no_of_source_words = count_words(source_words); + + /* Check if SOURCE_STRING was empty of words */ + if (no_of_source_words == 0) + { + answer.indexes = MALLOC (1 * sizeof(int)); + if (answer.indexes == NULL) + { + /* Gahh! Someone eats memory! */ + answer.no_of_matches = -1; + return answer; + } + answer.indexes[0] = -1; + answer.no_of_matches = 1; + return answer; + } + + + answer.no_of_matches = 0; + answer.indexes = NULL; + size_of_index_list = 0; + index = -1; + best_match = 1; /* At least one word */ + highest_priority = 1; + while (! s_empty (match_table[++index].name)) + { + first_non_matching = match (source_words, match_table[index].tokens, + collat_tab); + + if ( ( ! allow_trailing_words + && first_non_matching < no_of_source_words) + || ( number_of_words_must_match + && first_non_matching != count_words (match_table[index].tokens))) + { + continue; /* Try next entry in table */ + } + + if (first_non_matching < best_match) + continue; /* Try next entry in table */ + + if ( first_non_matching == best_match + && highest_priority > match_table[index].priority) + continue; + + /* If we reach this far, then we have a match that should be + * inserted in the table. But if it is a better match than any + * before, then we clear the table first. */ + if ( first_non_matching > best_match + || match_table[index].priority > highest_priority) + { + highest_priority = match_table[index].priority; + best_match = first_non_matching; + answer.no_of_matches = 0; + } + + /* Insert the match in the table */ + + /* Increase the size if necessary */ + if (answer.no_of_matches >= size_of_index_list) + { + temp_indexes = REALLOC (answer.indexes, + (size_of_index_list += chunk_size) + * sizeof(answer.indexes)); + if (temp_indexes == NULL) + { + /* Grumble! Out of memory. */ + FREE (answer.indexes); + answer.no_of_matches = -1; + return answer; + } + + answer.indexes = temp_indexes; + } + + highest_priority = match_table [index].priority; + answer.indexes[answer.no_of_matches] = index; + /* Find out where the arguments start. + * This value should not be used if more than one match is found. + */ + /* Special hack needed if no parameters */ + if (s_empty (source_words [first_non_matching].word)) + answer.arguments = EMPTY_STRING; + else + answer.arguments = + s_fsubstr(source_string, + source_words[first_non_matching]. + start_in_string, + END_OF_STRING); + answer.no_of_matches++; + } + + /* All matches found by now */ + + /* Strip trailing blanks from the argument */ + if (answer.no_of_matches == 1) + answer.arguments = s_strip_trailing (answer.arguments, separators); + + return answer; + +} /* END: parse() */ diff --git a/src/libraries/libcommon/parser.h b/src/libraries/libcommon/parser.h new file mode 100644 index 0000000000000000000000000000000000000000..922bb4416e9fe7ba4a42295f4ef54c3999e3aaff --- /dev/null +++ b/src/libraries/libcommon/parser.h @@ -0,0 +1,147 @@ +/* + * client/parser.h -- Header file for LysKOM command parsing routines + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * e-mail: Bellman@Lysator.LiU.SE + */ + + +#ifndef PARSER_H_ALREADY_INCLUDED__ +#define PARSER_H_ALREADY_INCLUDED__ + + +#include <misc-types.h> +#include <s-string.h> +#include <s-collat-tabs.h> + + + +/* + * Information about one word. If the field 'word' is + * EMPTY_STRING, then the struct is considered to be the last + * in an "array". BUG: "array" is wrong word + */ +typedef struct { + String word; + String_size start_in_string; +} Parse_token; + + +/* + * Information about one string to match against during parse(). + * A list of these should be passed to parse() as the CMD_TABLE + * parameter. The 'tokens' field is set by doing + * I.tokens = tokenize(I.name, Separators); + */ +typedef struct matching_info { + String name; /* Name to match against */ + Parse_token * tokens; /* Tokenized version of name */ + int priority; /* Normally in interval 1..15 */ +} Matching_info; + + + +/* + * Remove paranthesized "expressions" from the string STR by + * replacing them with the character SEPARATOR. + * Superflous close paranthesis are disregarded. + */ +extern void +remove_parenthesis (String * str, + char separator); + + + +/* + * Convert a String to a list of tokens (words). This list is + * easier to parse than a string (since the string would have to + * be tokenized first anyway). + * Returns NULL if any error occured (couldn't allocate memory). + */ +extern Parse_token * +tokenize (const String source, + const String separators); + + + +/* + * Count the number of tokens (words) in TOKEN_LIST. Used to + * set the NUMBER_OF_WORDS field in a 'Matching_info' object. + */ +extern int +count_words (const Parse_token * token_list); + + + +/* + * Free the list of tokens (// and the strings they are pointing to //). + * Free:ing NULL is a no-op. + */ +extern void +free_tokens (Parse_token * token_list); + + + +/* + * Returns the number of the first word of SOURCE that does + * not match PATTERN. A word "foo" in SOURCE matches "foobar" + * in PATTERN, but not vice versa. + */ +extern int +match (Parse_token * source, + Parse_token * pattern, + char collat_tab [ COLLAT_TAB_SIZE ] ); + + + +/* + * Contains the result of a parse(). + */ +typedef struct { + int no_of_matches; /* Number of found matches */ + int * indexes; /* List of indexes */ + String arguments; /* The arguments... */ +} Parse_info; + + +/* + * Searches for a matching string in the table 'match_table'. + * Some weird pattern matching is done. The 'ARGUMENTS' field of + * the result is not a separate String, but points into + * SOURCE_STRING. + * If ALLOW_TRAILING_WORDS is false, then SOURCE_STRING may not + * contain any trailing words. + * If NUMBER_OF_WORDS_MUST_MATCH is true, then all the words + * in from the entry in MATCH_TABLE must be present (possibly + * abbrevated) in SOURCE_STRING. + * parse().no_of_matches is -1 if an error occured (out of + * memory). + * If SOURCE_STRING is empty, i e does not contain any words, + * the 'no_of_matches' field is 1, and indexes[0] is -1. + * + * What? You want a description of how it matches? Forget it! BUG! + * Try for yourself, and you'll find out! + */ + +extern Parse_info +parse (String source_string, + Matching_info * match_table, + Bool allow_trailing_words, + Bool number_of_words_must_match, + String separators, + char collat_tab [ COLLAT_TAB_SIZE ] ); + + +#endif /* PARSER_H_ALREADY_INCLUDED__ */ diff --git a/src/libraries/libmisc/Makefile b/src/libraries/libmisc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cba454931e4816ba31a4457181930112b07c98c0 --- /dev/null +++ b/src/libraries/libmisc/Makefile @@ -0,0 +1,76 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR = /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR = $(TOPDIR)/scripts +endif + +TARGET = -DCLIENT + +include $(SCRIPTDIR)/import.make + + +# All directories that make should traverse to when doing clean etc. + + +LIBNAME = libmisc.a + +LIBOBJS = pom.o s-collat-tabs.o s-string.o zmalloc.o + +INSTALL-HDRS = pom.h s-collat-tabs.h s-string.h zmalloc.h + +#OBJECTS = numlist.o numlist2.o pom.o s-collat-tabs.o s-string.o \ +# testnumlist.o zmalloc.o + +all: $(LIBNAME) + +$(LIBNAME): $(LIBOBJS) + ar r $(LIBNAME) $? + ranlib $(LIBNAME) + +install: $(LIBNAME) install-headers + $(RM) $(LIBDIR)/$(LIBNAME) + cp $(LIBNAME) $(LIBDIR)/$(LIBNAME) + ranlib -t $(LIBDIR)/$(LIBNAME) + +install-headers: + (cd $(INCLUDEDIR); $(RM) $(INSTALL-HDRS)) + cp $(INSTALL-HDRS) $(INCLUDEDIR)/ + +testnumlist: testnumlist.o numlist.o + $(CC) -o testnumlist testnumlist.o numlist.o + + +clean: + rm -vf ${OBJECTS} *~ core temp-Makefile Distfile *.o + + +# Recreate the Makefile +include $(SCRIPTDIR)/Parallell-depend.make + + +tags: + etags -t $(INCLUDEDIR)/*.h *.[hc] + +specials:; + +include dependencies diff --git a/src/libraries/libmisc/README b/src/libraries/libmisc/README new file mode 100644 index 0000000000000000000000000000000000000000..922de6f141ccd00be6669372c76c34856d027ba6 --- /dev/null +++ b/src/libraries/libmisc/README @@ -0,0 +1,2 @@ +All utveckling i detta bibliotek sker p} LLL. +H{r ligger includefiler som {r gemensamma f|r server och klient. diff --git a/src/libraries/libmisc/dependencies b/src/libraries/libmisc/dependencies new file mode 100644 index 0000000000000000000000000000000000000000..370b62eafdad342cec263d8289646ef942f43deb --- /dev/null +++ b/src/libraries/libmisc/dependencies @@ -0,0 +1,15 @@ +numlist.o : numlist.c /users/ceder/gurka/lyskom/include/ansi/stdio.h \ + /users/ceder/gurka/lyskom/include/ansi/stdlib.h \ + /users/ceder/gurka/lyskom/include/ansi/stddef.h \ + /usr/gnu/lib/gcc-include/sys/types.h /usr/include/sys/types.h \ + /usr/gnu/lib/gcc-include/sys/stdtypes.h /usr/include/sys/stdtypes.h \ + /usr/include/sys/sysmacros.h /users/ceder/gurka/lyskom/include/misc-types.h \ + numlist.h +testnumlist.o : testnumlist.c \ + /users/ceder/gurka/lyskom/include/ansi/stdio.h \ + /users/ceder/gurka/lyskom/include/ansi/stdlib.h \ + /users/ceder/gurka/lyskom/include/ansi/stddef.h \ + /usr/gnu/lib/gcc-include/sys/types.h /usr/include/sys/types.h \ + /usr/gnu/lib/gcc-include/sys/stdtypes.h /usr/include/sys/stdtypes.h \ + /usr/include/sys/sysmacros.h /users/ceder/gurka/lyskom/include/misc-types.h \ + numlist.h diff --git a/src/libraries/libmisc/numlist.c b/src/libraries/libmisc/numlist.c new file mode 100644 index 0000000000000000000000000000000000000000..fe5caa4ec988f6ed5701c15dcf966ed320bf53d6 --- /dev/null +++ b/src/libraries/libmisc/numlist.c @@ -0,0 +1,615 @@ +/* + * File: numlist.c + * + * A numlist is supposed to be an efficient implementation of + * a list of numbers. One of the big features is intervals. + * + * Author: Inge Wallin + * + * Three plus signs (+++) denote places where more work may be needed. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <misc-types.h> + +#include "numlist.h" + + +/* ================================================================ */ +/* Some useful macros */ + + +#define IS_INTERVAL_START(x) (((x) & INTERVAL_MASK) == INTERVAL_START) +#define IS_INTERVAL_END(x) (((x) & INTERVAL_MASK) == INTERVAL_END) + +#define NUMBER_OF(x) ((x) & NUMBER_MASK) + +#define MAKE_INTERVAL_START(x) ((x) | INTERVAL_START) +#define MAKE_INTERVAL_END(x) ((x) | INTERVAL_END) + + +/* ================================================================ */ +/* Numlist_node */ + + +static Numlist_node * +numlist_node_create() +{ + Numlist_node * nln; + + nln = (Numlist_node *) malloc(sizeof(Numlist_node)); + if (nln == NULL) { + fprintf(stderr, "Virtual memory exhausted"); + abort(); + } + + nln->num_numbers = 0; + nln->next = NULL; + + return nln; +} + + + +/* + * Insert the number NUM at index INDEX in the numlist node NLN. + * All numbers starting at index INDEX and subsequent are moved + * one step back. + */ + +static void +numlist_node_insert_num(Numlist_node * nln, + int index, + u_long num) +{ + int i; + + for (i = nln->num_numbers; i > index; --i) + nln->numbers[i] = nln->numbers[i - 1]; + nln->numbers[index] = num; + ++nln->num_numbers; +} + + + +/* + * Delete the number with index INDEX from the node NODE. If this + * was the last number in the node, delete the entire node. PREV_NODE + * points to the node just before NODE and NL is the Numlist they + * both belong to. + */ + +static void +numlist_node_del_num(Numlist * nl, + Numlist_node * node, + Numlist_node * prev_node, + int index) +{ + int i; + + /* Delete the number from this node. */ + for (i = index; i < node->num_numbers - 1; ++i) + node->numbers[i] = node->numbers[i + 1]; + --(node->num_numbers); + + /* If this node became empty, delete it and fix all pointers. */ + if (node->num_numbers == 0) { + if (prev_node == NULL) { + nl->first = node->next; + if (nl->first == NULL) + nl->last = NULL; + } else { + prev_node->next = node->next; + if (nl->last == node) + nl->last = prev_node; + } + free(node); + } +} + + + +/* + * Split the node NODE into two nodes. The numbers starting with the + * index INDEX is put in the second (new) node and the other remain + * in the old one. NL points to the Numlist the node belongs to. + */ + +static void +numlist_node_split(Numlist * nl, + Numlist_node * node, + int index) +{ + Numlist_node * new_node; + int i; + + new_node = numlist_node_create(); + new_node->next = node->next; + node->next = new_node; + + for (i = index; i < node->num_numbers; ++i) + new_node->numbers[i - index] = node->numbers[i]; + + new_node->num_numbers = node->num_numbers - index; + node->num_numbers = index; + + if (nl->last == node) + nl->last = new_node; +} + + +/* ================================================================ */ +/* Numlist */ + + +/* + * Create a new, empty Numlist and return a pointer to it. + */ + +Numlist * +numlist_create() +{ + Numlist * nl; + + nl = (Numlist *) malloc(sizeof(Numlist)); + if (nl == NULL) { + fprintf(stderr, "Virtual memory exhausted"); + abort(); + } + + nl->first = NULL; + nl->last = NULL; + nl->last_num = NUMLIST_NO_NUMBER; + + return nl; +} + + + +/* + * Return TRUE if the Numlist NL is empty, otherwise return FALSE. + */ + +Bool +numlist_isempty(Numlist *nl) +{ + return nl->first == NULL; +} + + + +/* + * return TRUE if NUM is a member of the numlist NL, otherwise + * return FALSE. + */ + +Bool +numlist_member(Numlist *nl, u_long num) +{ + Numlist_node * nln; + u_long last; + int i; + + /* If num is bigger than the last number, return FALSE immediately. */ + last = numlist_last(nl); + if (last == NUMLIST_ERR || num > last) + return FALSE; + + nln = nl->first; + while (nln != NULL) { + if (num <= NUMBER_OF(nln->numbers[nln->num_numbers - 1])) { + for (i = 0; i < nln->num_numbers; ++i) { + + /* Check if we can abort the loop. */ + if (num < NUMBER_OF(nln->numbers[i])) + return FALSE; + + /* Take care of an interval. */ + if (IS_INTERVAL_START(nln->numbers[i])) { + if (NUMBER_OF(nln->numbers[i]) <= num + && num <= NUMBER_OF(nln->numbers[i + 1])) + return TRUE; + ++i; + } else { + if (nln->numbers[i] == num) + return TRUE; + } + } + } + + nln = nln->next; + } + return FALSE; +} + + + +/* + * Return the first number in the numlist NL. Also store a pointer + * to the first node, the index to this particular cell and the + * first number itself in the numlist. This makes it more efficient + * to get the next number later. + * + * If NL is empty, return the constant NUMLIST_ERR. + */ + +u_long +numlist_first(Numlist *nl) +{ + u_long first; + + if (numlist_isempty(nl)) { + return NUMLIST_ERR; + } else { + first = NUMBER_OF(nl->first->numbers[0]); + nl->last_num = first; + nl->last_node = nl->first; + nl->last_index = 0; + + return first; + } +} + + + +/* + * Return the last number in the numlist NL. If NL is empty, + * return the constant NUMLIST_ERR. + * + * Unlike numlist_first(), this routine does NOT set last_num + * and the other cache fields in NL. + */ + +u_long +numlist_last(Numlist *nl) +{ + Numlist_node * last; + + if (numlist_isempty(nl)) { + return NUMLIST_ERR; + } else { + last = nl->last; + return NUMBER_OF(last->numbers[last->num_numbers - 1]); + } +} + + + +/* + * Return the first number that is a member of the numlist NL and + * bigger than NUM. If there is no such number, the constant + * NUMLIST_ERR is returned. + */ + +u_long +numlist_next(Numlist *nl, u_long num) +{ + Numlist_node * nln; + int index; + int i; + + /* If we got NUM the last time, we have cached some info about */ + /* where to find the next entry. Use that info. */ + if (num == nl->last_num) { + nln = nl->last_node; + index = nl->last_index; + if (IS_INTERVAL_START(nln->numbers[index])) { + + /* Last number was in an interval. */ + if (num < NUMBER_OF(nln->numbers[index + 1])) { + nl->last_num = num + 1; + return num + 1; + } else { + ++index; + } + } + + ++index; + if (index < nln->num_numbers) { + nl->last_num = NUMBER_OF(nln->numbers[index]); + nl->last_index = index; + return nl->last_num; + } + + /* If we get here the next number is not in this node */ + /* but in the next. */ + nln = nln->next; + if (nln == NULL) { + nl->last_num = NUMLIST_NO_NUMBER; + return NUMLIST_ERR; + } else { + nl->last_num = NUMBER_OF(nln->numbers[0]); + nl->last_node = nln; + nl->last_index = 0; + + return nl->last_num; + } + } + + /* ...otherwise find NUM in the list and return the next number. */ + nln = nl->first; + ++num; + while (nln != NULL) { + if (num <= NUMBER_OF(nln->numbers[nln->num_numbers - 1])) { + for (i = 0; i < nln->num_numbers; ++i) { + + if (num <= NUMBER_OF(nln->numbers[i])) { + nl->last_num = NUMBER_OF(nln->numbers[i]); + nl->last_node = nln; + nl->last_index = i; + return nl->last_num; + } + + /* Take care of an interval. */ + if (IS_INTERVAL_START(nln->numbers[i])) { + if (num <= NUMBER_OF(nln->numbers[i + 1])) { + nl->last_num = num; + nl->last_node = nln; + nl->last_index = i; + + return num; + } else { + ++i; + } + } + } + } + nln = nln->next; + } + + return NUMLIST_ERR; +} + + + +/* + * Enter the number NUM into the numlist NL. If NL is already in + * NL, do nothing. + */ + +void +numlist_insert(Numlist *nl, u_long num) +{ + Numlist_node * nln; + Numlist_node * last; + int last_num; + int i; + int j; + + nl->last_num = NUMLIST_NO_NUMBER; + + last_num = numlist_last(nl); + if (last_num != NUMLIST_ERR && num <= last_num) { + nln = nl->first; + while (nln != NULL) { + if (num <= NUMBER_OF(nln->numbers[nln->num_numbers - 1])) { + for (i = 0; i < nln->num_numbers; ++i) { + if (num <= NUMBER_OF(nln->numbers[i])) + goto found; + } + } + nln = nln->next; + } + } + + /* If we get here, num is not found. It is also the case that num */ + /* is bigger than all numbers in the numlist. */ + last = nl->last; + if (last == NULL) { + + /* Empty numlist. */ + nl->first = nl->last = numlist_node_create(); + nl->first->num_numbers = 1; + nl->first->numbers[0] = num; + + } else if ((NUMBER_OF(last->numbers[last->num_numbers - 1]) == num - 1) + && IS_INTERVAL_END(last->numbers[last->num_numbers - 1])) { + /* Enter num into last interval */ + last->numbers[last->num_numbers - 1] = MAKE_INTERVAL_END(num); + + } else if (last->num_numbers < NUM_LONGS_IN_NUMLIST) { + /* There is room for num in the last Numlist_node. */ + if (last->numbers[last->num_numbers - 1] == num - 1) { + last->numbers[last->num_numbers - 1] + = MAKE_INTERVAL_START(num - 1); + last->numbers[last->num_numbers++] = MAKE_INTERVAL_END(num); + } else + last->numbers[last->num_numbers++] = num; + + + } else { + /* We have to create a new Numlist_node to host num. */ + nl->last = numlist_node_create(); + last->next = nl->last; + nl->last->num_numbers = 1; + nl->last->numbers[0] = num; + } + return; + + found: + /* Here we have found a number that is bigger than num. */ + /* nln points to the Numlist_node and i is the index to it. */ + + /* If num is already in the list, do nothing. */ + if (NUMBER_OF(nln->numbers[i]) == num + || IS_INTERVAL_END(nln->numbers[i])) + return; + + /* Step through the different cases and take appropriate action. */ + if (IS_INTERVAL_START(nln->numbers[i]) + && NUMBER_OF(nln->numbers[i]) == num + 1) { + + /* Enter num into the next interval. */ + nln->numbers[i] = MAKE_INTERVAL_START(num); + + /* +++Take care of the case that two intervals could be */ + /* collapsed into one, e.g. like 17-21, 22-31 => 17-31. */ + + } else if (i > 0 + && IS_INTERVAL_END(nln->numbers[i - 1]) + && NUMBER_OF(nln->numbers[i - 1]) == num - 1) { + + /* Enter num into the previous interval. */ + nln->numbers[i - 1] = MAKE_INTERVAL_END(num); + + } else if (nln->num_numbers < NUM_LONGS_IN_NUMLIST) { + + /* Squeeze in num. There is room in this Numlist_node. */ + for (j = nln->num_numbers; j > i; --j) + nln->numbers[j] = nln->numbers[j - 1]; + if (i > 0 && nln->numbers[i - 1] == num - 1) { + nln->numbers[i - 1] = MAKE_INTERVAL_START(num - 1); + nln->numbers[i] = MAKE_INTERVAL_END(num); + } else if (i < nln->num_numbers - 1 + && nln->numbers[i + 1] == num + 1) { + nln->numbers[i] = MAKE_INTERVAL_START(num); + nln->numbers[i + 1] = MAKE_INTERVAL_END(num + 1); + } else { + nln->numbers[i] = num; + } + + nln->num_numbers++; + + } else { + /* Squeeze in num. There is no room in this Numlist_node. */ + /* +++This implementation is a bit crude. We should split */ + /* the node as evenly as possible. */ + + numlist_node_split(nl, nln, i); + nln->numbers[nln->num_numbers++] = num; + } + + /* +++We never take care of the case that two intervals in adjacent */ + /* nodes could be collapsed into one. Should we? */ + return; +} + + + +/* + * Delete the number NUM from the Numlist NL. If NUM is not + * a member of NL, do nothing. + */ + +void +numlist_delete(Numlist *nl, u_long num) +{ + Numlist_node * nln1; + Numlist_node * nln2; + int last_num; + int i; + int j; + + nl->last_num = NUMLIST_NO_NUMBER; + + last_num = numlist_last(nl); + if (last_num == NUMLIST_ERR || num > last_num) + return; + + nln1 = nl->first; + nln2 = NULL; + while (nln1 != NULL) { + if (num <= NUMBER_OF(nln1->numbers[nln1->num_numbers - 1])) { + for (i = 0; i < nln1->num_numbers; ++i) { + if (num == nln1->numbers[i] /* An ordinary number */ + || (IS_INTERVAL_START(nln1->numbers[i]) + && NUMBER_OF(nln1->numbers[i]) <= num + && num <= NUMBER_OF(nln1->numbers[++i]))) + goto found; + + /* If we are already past the number, it is not here */ + /* ==> return. */ + if (num < NUMBER_OF(nln1->numbers[i])) + return; + } + } + nln2 = nln1; + nln1 = nln1->next; + } + return; + + /* When we get here, nln1 points to the node where the number */ + /* resides, nln2 points to the node before if not NULL, and i */ + /* i is the index into the node. If the number is within an */ + /* interval, i points to the end of the interval (++i above). */ + found: + if ((nln1->numbers[i] & INTERVAL_MASK) == 0) { + /* An ordinary number. */ + numlist_node_del_num(nl, nln1, nln2, i); + + } else { + /* An interval. */ + if (NUMBER_OF(nln1->numbers[i]) == num) { + /* The number is at the end of the interval. */ + --(nln1->numbers[i]); + if (NUMBER_OF(nln1->numbers[i]) + == NUMBER_OF(nln1->numbers[i - 1])) { + + numlist_node_del_num(nl, nln1, nln2, i); + nln1->numbers[i - 1] &= NUMBER_MASK; + } + + } else if (NUMBER_OF(nln1->numbers[i - 1]) == num) { + /* The number is at the start of the interval. */ + ++(nln1->numbers[i - 1]); + if (NUMBER_OF(nln1->numbers[i]) + == NUMBER_OF(nln1->numbers[i - 1])) { + + numlist_node_del_num(nl, nln1, nln2, i); + nln1->numbers[i - 1] &= NUMBER_MASK; + } + + } else if (NUMBER_OF(nln1->numbers[i - 1]) == num - 1 + && NUMBER_OF(nln1->numbers[i]) == num + 1) { + /* The interval is only 3 numbers */ + nln1->numbers[i - 1] &= NUMBER_MASK; + nln1->numbers[i] &= NUMBER_MASK; + + } else { + /* The number is within the interval. We must split it. */ + if (IS_INTERVAL_END(nln1->numbers[i])) + --i; + + /* If there is not room for two new numbers, split the node. */ + if (nln1->num_numbers > NUM_LONGS_IN_NUMLIST - 2) { + if (i < NUM_LONGS_IN_NUMLIST / 2) { + /* Split the node after the interval and keep it here. */ + numlist_node_split(nl, nln1, i + 2); + } else { + /* Split the node before the interval */ + /* and use the new node. */ + numlist_node_split(nl, nln1, i); + nln1 = nln1->next; + i = 0; + } + } + + /* Now nln1 points to the node with the interval and */ + /* i is the index to the start of the interval. */ + if (NUMBER_OF(nln1->numbers[i]) == num - 1) { + /* NUM is second element ==> leave only one to the left. */ + numlist_node_insert_num(nln1, i, + NUMBER_OF(nln1->numbers[i])); + nln1->numbers[i + 1] += 2; + + } else if (NUMBER_OF(nln1->numbers[i + 1]) == num + 1) { + /* NUM is second last element ==> leave only one to */ + /* the right. */ + numlist_node_insert_num(nln1, i + 2, + NUMBER_OF(nln1->numbers[i + 1])); + nln1->numbers[i + 1] -= 2; + + } else { + /* NUM is deep inside the interval */ + /* ==> Make 2 new intervals. */ + for (j = nln1->num_numbers + 1; j >= i + 2; --j) + nln1->numbers[j] = nln1->numbers[j - 2]; + nln1->numbers[i + 1] = MAKE_INTERVAL_END(num - 1); + nln1->numbers[i + 2] = MAKE_INTERVAL_START(num + 1); + nln1->num_numbers += 2; + } + } + } +} diff --git a/src/libraries/libmisc/numlist.h b/src/libraries/libmisc/numlist.h new file mode 100644 index 0000000000000000000000000000000000000000..c0f4c0f94b20f52fc44b319bf52ee7f8965c7513 --- /dev/null +++ b/src/libraries/libmisc/numlist.h @@ -0,0 +1,92 @@ +/* + * File: numlist.h + * + * A numlist is an ordered list of numbers. One of the big features + * of this implementation is intervals. + * + * Author: Inge Wallin + */ + + +#ifndef NUMLIST__H +#define NUMLIST__H + +#include <sys/types.h> + + +#define INTERVAL_MASK 0xc0000000 +#define NUMBER_MASK 0x3fffffff +#define INTERVAL_START 0x80000000 +#define INTERVAL_END 0x40000000 + + +/* This constant is returned whenever there are no more fitting values */ +/* for a call, e.g. when numlist_first() is called with an empty Numlist. */ + +#define NUMLIST_ERR 0xffffffff + + +/* This constant is stored in the field last_num when no previous */ +/* number is stored. */ + +#define NUMLIST_NO_NUMBER 0xffffffff + + +/* + * One int + 13 longs + one pointer + the length info that + * malloc adds makes 64 bytes. This should make allocation fairly + * efficient. + */ + +/* #define NUM_LONGS_IN_NUMLIST 13 */ +#define NUM_LONGS_IN_NUMLIST 5 + + +typedef struct numlist_node Numlist_node; +typedef struct numlist Numlist; + +struct numlist_node { + int num_numbers; + u_long numbers[NUM_LONGS_IN_NUMLIST]; + Numlist_node * next; +}; + + +struct numlist { + Numlist_node * first; + Numlist_node * last; + + /* The following info is used only for speeding up numlist_next(). */ + u_long last_num; /* The last number returned. */ + Numlist_node * last_node; /* The node containing the last number... */ + int last_index; /* ...and the index to it. */ +}; + + +/* ================================================================ */ +/* Prototypes for all global functions in the numlist package. */ + + +Numlist *numlist_create(void); +Bool numlist_isempty(Numlist *); +Bool numlist_member(Numlist *, u_long); +u_long numlist_first(Numlist *); +u_long numlist_last(Numlist *); +u_long numlist_next(Numlist *, u_long); +void numlist_insert(Numlist *, u_long); +void numlist_delete(Numlist *, u_long); + +/* + * Useful (?) but not yet implemented: + * + * void numlist_destroy(Numlist *); + * void numlist_insert_interval(Numlist *, u_long, u_long); + * void numlist_delete_interval(Numlist *, u_long, u_long); + * Numlist *numlist_union(Numlist *, Numlist *); + * Numlist *numlist_intersection(Numlist *, Numlist *); + * Numlist *numlist_difference(Numlist *, Numlist *); + * void numlist_print(FILE *, Numlist *); + * void numlist_read(FILE *, Numlist *); + */ + +#endif /* NUMLIST__H */ diff --git a/src/libraries/libmisc/numlist2.c b/src/libraries/libmisc/numlist2.c new file mode 100644 index 0000000000000000000000000000000000000000..2124a45400692a7ae1bdf578960744b3ddd5298c --- /dev/null +++ b/src/libraries/libmisc/numlist2.c @@ -0,0 +1,99 @@ +/* + * File: numlist2.c + * + * This file is supposed to be a reference while testing numlist. + * + * Author: Inge Wallin + */ + + +#include <stdio.h> +#include <stdlib.h> + +#include <misc-types.h> + +#include "numlist2.h" + + +Numlist * +Numlist_create() +{ + Numlist * nl; + int i; + + nl = (Numlist *) malloc(sizeof(Numlist)); + if (nl == NULL) { + fprintf(stderr, "Virtual memory exhausted"); + abort(); + } + + for (i = 0; i < NUM_CELLS; ++i) + nl->cells[i] = 0; + + return nl; +} + + +Bool +numlist_isempty(Numlist *nl) +{ + int i; + + for (i = 0; i < NUM_CELLS; ++i) + if (nl->cells[i] != 0) + return FALSE; + + return TRUE; +} + + +Bool +numlist_member(Numlist *nl, u_long num) +{ + return (nl->cells[num / 32] & ((u_long) 1 << (num & 31))) != 0; +} + + +u_long +numlist_first(Numlist *nl) +{ + int i; + int j; + + if (numlist_isempty(nl)) + return NUMLIST_ERR; + + for (i = 0; i < NUM_CELLS; ++i) { + if (nl->cells[i] != 0) { + for (j = 31; j >= 0; --j) { + if ((nl->cells[i] & ((u_long) 1 << j)) != 0) + return i * 32 + j; + } + } + } + + return NUMLIST_ERR; +} + + +u_long +numlist_next(Numlist *nl, u_long num) +{ + /* NYI */ + return NUMLIST_ERR; +} + + +void +numlist_insert(Numlist *nl, u_long num) +{ + nl->cells[num / 32] |= ((u_long) 1 << (num & 31)); +} + + +void +numlist_delete(Numlist *nl, u_long num) +{ + nl->cells[num / 32] &= ~((u_long) 1 << (num & 31)); +} + diff --git a/src/libraries/libmisc/numlist2.h b/src/libraries/libmisc/numlist2.h new file mode 100644 index 0000000000000000000000000000000000000000..da0a594120bd80d0535c2a8b4e2e0090803725ad --- /dev/null +++ b/src/libraries/libmisc/numlist2.h @@ -0,0 +1,35 @@ +/* + * File: numlist2.h + * + * This file is supposed to be a reference while testing numlist. + * + * Author: Inge Wallin + */ + + +#ifndef NUMLIST2__H +#define NUMLIST2__H + +#include <sys/types.h> + + +#define NUMLIST_ERR 0xffffffff + +#define MAX_NUMS 131072 +#define NUM_CELLS (MAX_NUMS / 32) + +typedef struct { + u_long cells[NUM_CELLS]; +} Numlist; + + +Numlist *numlist_create(void); +Bool numlist_isempty(Numlist *); +Bool numlist_member(Numlist *, u_long); +u_long numlist_first(Numlist *); +u_long numlist_next(Numlist *, u_long); +void numlist_insert(Numlist *, u_long); +void numlist_delete(Numlist *, u_long); + + +#endif /* NUMLIST2__H */ diff --git a/src/libraries/libmisc/testnumlist b/src/libraries/libmisc/testnumlist new file mode 100755 index 0000000000000000000000000000000000000000..103245d0a3816fd38dda3481d15c1add2871998a Binary files /dev/null and b/src/libraries/libmisc/testnumlist differ diff --git a/src/libraries/libmisc/testnumlist.c b/src/libraries/libmisc/testnumlist.c new file mode 100644 index 0000000000000000000000000000000000000000..e63e154732a8f90777901d4febe4e3242719cf63 --- /dev/null +++ b/src/libraries/libmisc/testnumlist.c @@ -0,0 +1,109 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <misc-types.h> + +#include "numlist.h" + + +/* ================================================================ */ +/* Some useful macros */ + + +#define IS_INTERVAL_START(x) (((x) & INTERVAL_MASK) == INTERVAL_START) +#define IS_INTERVAL_END(x) (((x) & INTERVAL_MASK) == INTERVAL_END) + +#define NUMBER_OF(x) ((x) & NUMBER_MASK) + +#define MAKE_INTERVAL_START(x) ((x) | INTERVAL_START) +#define MAKE_INTERVAL_END(x) ((x) | INTERVAL_END) + + +/* ================================================================ */ + + +void +numlist_node_print(Numlist_node *nln) +{ + int i; + u_long num; + + putchar('['); + for (i = 0; i < NUM_LONGS_IN_NUMLIST; ++i) { + if (i < nln->num_numbers) { + num = nln->numbers[i]; + printf("%c%5U%c,", IS_INTERVAL_START(num) ? '<' : ' ', + NUMBER_OF(num), IS_INTERVAL_END(num) ? '>' : ' '); + } else { + printf(" ,"); + } + } + putchar(']'); + putchar('\n'); +} + + + +void +numlist_print(Numlist *nl) +{ + Numlist_node * nln; + + printf("last_num = %U\n", nl->last_num); + printf("last_index = %U\n", nl->last_index); + nln = nl->first; + while (nln != NULL) { + numlist_node_print(nln); + nln = nln->next; + } + putchar('\n'); +} + + + +int +main() +{ + Numlist * nl; + Bool finished; + + nl = numlist_create(); + puts("Empty numlist:"); + numlist_print(nl); + + finished = FALSE; + while (!finished) { + char command; + u_long num; + + scanf("\n%c%U", &command, &num); + switch (command) { + case 'i': + numlist_insert(nl, num); + printf("%U inserted\n", num); + numlist_print(nl); + break; + + case 'd': + numlist_delete(nl, num); + printf("%U deleted\n", num); + numlist_print(nl); + break; + + case 'q': + finished = TRUE; + break; + + case ' ': + case '\n': + break; + + default: + printf("Unrecognized command: %c\n", command); + break; + } + } + + return 0; +} + diff --git a/src/server/Makefile b/src/server/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..d09543a8a3cd7122b780ec0765151870718aaf0c --- /dev/null +++ b/src/server/Makefile @@ -0,0 +1,168 @@ +# Makefile for LysKOM +# +############################################################################### +# +# SPECIAL CONSIDERATIONS: +# +# - Requires GNU make. +# - CC, OPTIMIZE-FLAGS and other make variables are passed down +# in the environment. +# - C compiler must be ANSI conformant. +# +############################################################################### +# +# SPECIAL TARGETS: +############################################################################### + +# Directories that you might want to override via the environment. + +ifndef TOPDIR +TOPDIR := /usr/lyskom/src +endif + +ifndef SCRIPTDIR +SCRIPTDIR := $(TOPDIR)/scripts +endif + +include $(SCRIPTDIR)/import.make + + +DESTDIR = /usr/lyskom/bin + +HDRS = admin.h isc-parse.h prot-a-output.h async.h isc.h \ + prot-a-parse.h cache.h limits.h prot-a-send-async.h connections.h \ + log.h prot-a.h dbck-cache.h lyskomd.h ram-output.h disk-cache.h \ + manipulate.h ram-parse.h end-of-atomic.h memory.h send-async.h exp.h \ + minmax.h smalloc.h internal-connections.h mux-parse.h \ + std-disclaimer.h internal-services.h mux.h text-garb.h \ + version.incl cache-node.h + +# LIBS = -L/usr/local/lib -ldebug-malloc -lisc -lresolv +# /usr/local/lib is searched normally, and the -L flag is not supported by +# DYNIX. /ceder + +LIBS = -lisc -lmisc -llyskom-server -lansi + +TARGET = -DSERVER + + +# Files that implements protocol A. +PROTA = prot-a-output.o prot-a-parse-arg.o prot-a-parse.o prot-a.o \ + prot-a-send-async.o + +PROTA_SRCS = prot-a-output.c prot-a-parse-arg.c prot-a-parse.c prot-a.c \ + prot-a-send-async.c + +MUX = mux.o mux-parse.o + +MUX_SRCS = mux.c mux-parse.c +# Implementations of the atomic calls. + +ATOMS = text.o membership.o person.o conference.o session.o admin.o +ATOMS_SRCS = text.c membership.c person.c conference.c session.c admin.c + +# These files are needed by all versions of the LysKOM server. +GENOBJS = connections.o log.o $(ATOMS) \ + kom-types.o \ + send-async.o config.o text-garb.o \ + missing-ansi.o isc-parse.o memory.o $(PROTA) $(MUX) \ + internal-connections.o + +GEN_SRCS = connections.c log.c $(ATOMS_SRCS) \ + kom-types.c \ + send-async.c config.c text-garb.c \ + missing-ansi.c isc-parse.c memory.c $(PROTA_SRCS) $(MUX_SRCS) \ + internal-connections.c + +# Files that are necessary for ramkomd. + +RAMOBJS = ramkomd.o ram-smalloc.o ram-cache.o ram-parse.o ram-output.o \ + end-of-atomic.o string-malloc.o +RAM_SRCS = ramkomd.c ram-smalloc.c ram-cache.c ram-parse.c ram-output.c \ + end-of-atomic.c string-malloc.c + +# Files for diskomd. + +DISKOBJS = ramkomd.o ram-smalloc.o simple-cache.o ram-parse.o ram-output.o \ + disk-end-of-atomic.o cache-node.o string-malloc.o + +DISK_SRCS = ramkomd.c ram-smalloc.c simple-cache.c ram-parse.c ram-output.c \ + disk-end-of-atomic.c cache-node.c string-malloc.c + +# Files that are necessary for lyskomd. +LYSOBJS = cache.o lyskomd.o smalloc.o +LYS_SRCS = cache.c lyskomd.c smalloc.c + +DBCK = dbck.o dbck-cache2.o ram-smalloc.o ram-parse.o config.o\ + kom-types.o\ + missing-ansi.o ram-output.o memory.o + +DBCK_SRCS = dbck.c dbck-cache2.c ram-smalloc.c ram-parse.c config.c\ + kom-types.c\ + missing-ansi.c ram-output.c memory.c + + +SPECIALS = call-switch.incl com.h fnc-def-init.incl prot-a-parse-arg.c\ + prot-a-parse-arg.h fncdef-no-str-limit.txt + +SRCS = $(GEN_SRCS) $(RAM_SRCS) $(DISK_SRCS) $(LYS_SRCS) $(DBCK_SRCS) + +PROGRAMS = ramkomd diskomd dbck + + +all: $(PROGRAMS) + +ramkomd: $(RAMOBJS) $(GENOBJS) + $(CC) $(LDFLAGS) -o ramkomd $(RAMOBJS) $(GENOBJS) $(LIBS) + +diskomd: $(DISKOBJS) $(GENOBJS) + $(CC) $(LDFLAGS) -o diskomd $(DISKOBJS) $(GENOBJS) $(LIBS) + +lyskomd: + $(CC) $(CFLAGS) -o lyskomd + +dbck: $(DBCK) + $(CC) $(LDFLAGS) -o dbck $(DBCK) $(LIBS) + +call-switch.incl: call-switch.awk fncdef-no-str-limit.txt + $(AWK) -f call-switch.awk fncdef-no-str-limit.txt > call-switch.incl + +com.h: com-h.awk fncdef-no-str-limit.txt + $(AWK) -f com-h.awk fncdef-no-str-limit.txt > com.h + +fnc-def-init.incl: fnc-def-init.awk fncdef-no-str-limit.txt + $(AWK) -f fnc-def-init.awk fncdef-no-str-limit.txt > fnc-def-init.incl + +prot-a-parse-arg.c: prot-a-parse-arg-c.awk fncdef.txt prot-a-parse-arg.h + $(AWK) -f prot-a-parse-arg-c.awk fncdef.txt > prot-a-parse-arg.c + +prot-a-parse-arg.h: prot-a-parse-arg-h.awk fncdef-no-str-limit.txt + $(AWK) -f prot-a-parse-arg-h.awk fncdef-no-str-limit.txt > \ + prot-a-parse-arg.h + +fncdef-no-str-limit.txt: fncdef.txt + (echo \# Do not edit this file! It is generated from fncdef.txt.;\ + cat fncdef.txt) | sed 's/([^)]*)//g' > fncdef-no-str-limit.txt + + +install: $(PROGRAMS) + echo Server not installed. +# cp diskomd $(DESTDIR)/ramkomd # The utilites wants ramkomd. +# cp dbck $(DESTDIR)/ +# strip $(DESTDIR)/dbck +# Don't strip ramkomd - we want debugging info! + +clean: + rm -vf *.o *~ core $(PROGRAMS) $(SPECIALS) TAGS + +specials: $(SPECIALS) + +tags: $(SRCS) $(HDRS) + rcs -l TAGS + rm -f TAGS + etags -t $(INCLUDEDIR)/*.h *.[hc] + echo " " | ci TAGS + +include $(SCRIPTDIR)/Parallell-depend.make + +include dependencies diff --git a/src/server/free.gdb b/src/server/free.gdb new file mode 100644 index 0000000000000000000000000000000000000000..278acd9058cc89eda508a4fb78f424eba06a472e --- /dev/null +++ b/src/server/free.gdb @@ -0,0 +1,11 @@ +break sfree if ptr != 0 +commands +silent +echo --- sfree ---\n +echo Arg: +output ptr +echo \n +bt +echo =========\n +cont +end diff --git a/src/server/malloc.gdb b/src/server/malloc.gdb new file mode 100644 index 0000000000000000000000000000000000000000..e76fc55dd572526429e267c5a65d8e604b683f26 --- /dev/null +++ b/src/server/malloc.gdb @@ -0,0 +1,12 @@ +commands +silent +echo --- smalloc ---\n +echo Arg: +output size +echo \nVal: +output p +echo \n +bt +echo =========\n +cont +end diff --git a/src/server/realloc.gdb b/src/server/realloc.gdb new file mode 100644 index 0000000000000000000000000000000000000000..a65ad2e765e8b6acfa42a93d14ad07032207c81f --- /dev/null +++ b/src/server/realloc.gdb @@ -0,0 +1,14 @@ +commands +silent +echo --- srealloc ---\n +echo Arg: +output size +echo \nVal: +output new_ptr +echo \nOld: +output ptr +echo \n +bt +echo =========\n +cont +end