Homepage(german)     Computer stuff [deutsch]

Mini C libraries

Who doesn't know this: You want to quickly write a little program, and always the same tasks come up: lists, parsing of configuration files or of command line options. For all those things there are of course libraries. But who wants to link a dozen of libraries à 100KByte, whose full functionality is not at all needed, for every small program? Who wants to call x preprocessors before compiling?

Because I didn't want to, here are some very lightweighted C-libraries, I wrote in the course of time. Their capabilities are limited (except in the case of the list-library) to the absolutely necessary. They are not suited for bigger projects, but are thought for small and quick hacks.

All libraries consist of one or two c- and h-files. The KByte-statements are rounded to integers. All libraries are under the GNU Lesser GPL or under the BSD-licence. They run on my Linux-boxes (SuSE6.4 and 7.0), but should also run on other Linux-systems without any problems. Except for the ftp- and the nntp-library they should compile on other systems too, perhaps with some minor adaptations.

In the moment some of the libraries are still commented in german and the documentation is german too. If this is the case, I have remarked it here in this file.

Copyright: The libraries are partly under the GNU Lesser Public Licence (the former Library Public Licence), but mostly under the BDS-licence. In case of doubt one has to read to documentation. On the homepage of GNU the exact wording of the Lesser Public Licence can be found.

Operating system: I wrote and tested the libraries on my linux system. Except for the ftp- and the nntp-library it should be easily possible to adapt them to other systems, especially if the GNU C library is used.


Doubly linked lists

lists.1.41.tgz (11K) [The C file is 18K.]

(requires only <stdio.h> and <malloc.h>)

This library implements doubly linked lists. Beside the obligatory functions for inserting and removing list elements at arbitrary positions, concatting, copying, deleting etc. of lists, the rather comfortable work with sorted lists is supported. For subsequent sorting of lists the bubblesort- and the mergesort-algorithms are implemented.

Here are two examples, how to handle lists: In the first example the string s is inserted into a sorted list l at the correct position:

   insert_sorted_element (l, s, strcmp);

In the second example all values of the lists l are to be processed:

  list_t *p=l;
  while ((p=p->next)) {
      /* do something with p->val */
    }

State: Except for the sorting routines I frequently used this library. Gross mistakes are improbable.


Hashtables

hasht.1.1.tgz (6K) [The C file is 4K.]

(requires the list-library from above)

This library implements hashtables: Inserting and removing of entries, quick searching of values. Conversion of lists into hashtables and vice versa. The hash-function has to be provided by the user.

The html-documentation (only german) contains a (very very) short introduction to hashtables in general.

State: Seems to work, but was not seriously used by me. Beta.


Reading of configuration files

rconfig.1.2.tgz (5K) [The C file is 5KB.]

(requires <malloc.h>, <stdio.h>, <string.h> and <stdlib.h>.)

This is a library reading simple configuration files, which look as follows:

   OPTION_NAME = OPTION_VALUE

It only reads the values as char*. The possibly necessary conversion to numeric types has to be done by the application.

To the function a list of all possible option names and the name of the configuration file has to be passed. It then reads the file and tries to assign values to the options. The following list gives an overview over what the function does and what not:

Furthermore there is a function, which may help to build the name of the configuration file with complete path. (E.g. it does the expansion of ~ to the home directory of the user.)

In the moment comments and documentation are only in german.

State: I used this library several times, and there were no real problems. Because of the limited functionality gross mistakes are improbable.


Reading command line options

pclo1-0.1.tgz (2.5K) [The C file is 6K.]

Tries to find options and their parameters in the parameters of the command line, and is rather easy to use.

State: Some of the more exotic features weren't used often by me. But all "normal" things seem to work quiet well.


Recursively going down subdirectories

libfind-0.3.tgz (1K) [The C file is 4.5K.]

(requires stdio.h, sys/types.h, sys/stat.h, unistd.h, dirent.h, string.h)

The libfind only contains one small function. It takes the name of a directory and (possibly) two function pointers. It goes down recursively into all subdirectories and calls the functions given for every found file. And nothing more.

State: Because of the very limited functionality mistakes are improbable.


Parsing of mathematical expressions

fpar-0.5.tgz (7K) [The two C files are 12KB together.]

(requires stdio.h, malloc.h, string.h und stdlib.h)

fpar is a very small function parser, i.e. a C library, which parses a mathematical expression in a string, and builds a treelike structure from it, which contains the logical structure of the expression and can be evaluated.

Despite of its smallness the library is very simple to extend, even, if one wants, during runtime. In the moment the c file starts with the following definition:

term_t op[] = {
  { "#+#", left , base_add },  /* addition */
  { "#-#", left , base_sub },  /* subtraction */
  { "#*#", left , base_mult},  /* multiplication */
  { "#/#", left , base_div },  /* division */
  { "sqrt#",left, base_sqrt},  /* squareroot */
  { "sin#",left , base_sin },  /* sinus */
  { "cos#",left , base_cos },  /* cosinus */
  { "tan#",left , base_tan },  /* tangens */
  { "exp#",left , base_exp },  /* exponential function */
  { "ln#", left , base_ln  },  /* natural logarithm */
  { "-#",  left , base_neg },  /* the negative */
  { "#^#", left , base_pow },  /* power */
  { "(#)", right, base_id  },  /* identity, but with high priority */
  { "x",   left , base_x   },  /* free variable */
  { NULL,  right, NULL }
};

Further operations, even with more than two parameters and with different syntax simply can be inserted here according to their priority. In the case, where the expression is to be evaluated, a function, which does evaluate the new operation, is to be given. (Here these are the base_...-functions.) There is no special code for the functions above. Unfortunately this generality has lead to a certain abstractness, and the code is not simple to understand.

In the moment the library works with real numbers (or more precise: double numbers). But is should not be difficult to change it to other types, even selfdefined types.

Comments, a small txt documentation and a small test program are in the package.

State: I wrote this library for testing my skill, but didn't really use it. When I tested it, it seemed to work rather well: Beta.


Parsing of HTTP server log files

ploglib-0.3.tgz (16K) [The C file is 15KB.]

(requires some standard include files, the regex.h, and for the numeric conversion of IP-addresses sys/socket.h, netinet/in.h and arpa/inet.h.)

With the help of the ploglib it is possible to get most of the relevant information contained in the log files of HTTP-servers. The core function of the library is the function

   access_t *parse_log_line (char *line, logformat_t *lf);

The returned (newly allocated) struct contains the most important informations of the log line line, as e.g. the time, the IP of the requesting client, the response code of the server etc..

Unfortunately there is a snag: The library has to know, which log format is used. This information is to be given with the help of a regular expression, which contains some additional terms. More precise information can be taken from the documentation contained in the package. But it is not necessary to be a specialist for regular exporessions to understand how it works.

This library too is a small and easy hack. It it neither very fast, nor very mighty, nor very user-friendly, but it fulfils its purpose. On my Pentium1 with 166MHz it parses about 250-300 lines per second.

The documentation contains a rather detailed description, how to extend it. Since version 0.3 there is also an english documentation.

State: I used this library in several programs, but always with the same logformat. But it seems to work rather reliably.


FTP

ftpmlib.1.3.tgz (14K) [The C file is 29KB.]

(requires a lot of standard include files, among them of course the include files for networking: stdio.h, malloc.h, stdlib.h, string.h, errno.h, netdb.h, sys/types.h, netinet/in.h, arpa/inet.h, sys/socket.h, unistd.h, ctype.h)

The ftp-mini-lib (ftpmlib) implements parts of the FTP protocol, as defined in RFC959. I didn't write it to do more complicated things as initiating the transfer of files between two ftp-servers or resumption of interrupted transfers. I simply wanted to download and upload files, make directories or remove files on the server. In the moment there isn't even the possibility to use a proxy.

Here is an example, how simple the library can be used: A connection to a ftp-server is established, a new directory newdir is made. The current directory is changed to newdir, a file localfile is uploaded and saved as remotefile on the remote side. (All things carelessly without testing for errors. This causes the many NULLs.

   ftp_server *fs = ftpserver_connect ("ftp.somedomain.de", 0, NULL, NULL);
   ftp_logon (fs, "username", "password", NULL, NULL, NULL);
   ftp_set_transfer_type (fs, TTYPE_1_IMAGE, NULL, NULL); /* set to binary-mode */
   mk_working_dir (fs, 1, "newdir", NULL, NULL);
   ftp_change_dir (fs, 0, "newdir", NULL, NULL);
   ftp_put_file (fs, "localname", "remotename", NULL, NULL);
   ftpserver_close (fs, NULL, NULL);

In this case the both lines ftp_change_dir and ftp_put_file should be merged to

   ftp_put_file (fs, "localname", "newdir/remotename", NULL, NULL);

Status: I didn't go to the trouble of manipulating an ftp server to provoke errors. And I didn't had the possibility to test the library with different servers. It works with my server and the server of my provider. In particular the error processing still could contain some gross mistakes. Furthermore it was one of my first attempts to network programming. So I would look upon this library as in Alpha stage.

The library is threadsafe. Timeouts can be set.

(From version 1.0 to 1.1 the API was changed slightly.)

There is a similar project of about the same size and functionality: The ftplib of Thomas Pfau.


NNTP

nntpmlib-0.2.1.tgz (24K) [The C file is 23KB.]

(requires a lot of standard include files, among them of course the include files for networking: stdio.h, malloc.h, stdlib.h, string.h, errno.h, netdb.h, sys/types.h, netinet/in.h, sys/socket.h, unistd.h)

The nnptmlib implements a small part of the NNTP protocol (RFC0977) and of the common NNTP extensions (RFC2980), seen from the client side. Up to this moment there is only one implemented command of the latter RFC. Nevertheless the functionality of this library is enough to implement a simple news-reader, particularly since most of the common NNTP extensions aren't implemented by all servers.

In the following example a connection to a news server is established and a list of all groups is printed to the standard output. In the example there is no error processing. Therefore the many NULLs.

   nntp_server *ns;
   char *line;

   ns = nntp_connect ("news.somewhere.de", 119, NULL, NULL, NULL);
   nntp_list_groups (ns, NULL, NULL);
   while ((line = get_line_from_server(ns, NULL))) {
      printf ("%s\n", line);
      free (line);
      }
   nntp_close (ns, NULL, NULL);

There are some very practical functions, which help, if one wants to implement own NNTP commands. The library is (in my opinion) rather well structured, and it should be easy to extend.

State: I used this library with three different news servers, but didn't test all commands with all servers. There weren't bigger problems.


HTTP

httpmlib-0.4.tgz (8K) [Die C file is 17K.]

(requires some standard header files, among them of course those for networking)

The httpmlib is a rather rudimentary API for HTTP requests. It helps constructing and sending HTTP requests and reading and parsing the answer of the server. The responsibility for interpreting this answer remains mainly at the user of the library.

As high level API there exist only HEAD and GET-methods. After a GET the user can read the file requested from a FILE* stream. Other features:

Disadvantages are:


Homepage(german)     Computer stuff by Michael Becker, 12/2000. Translated: 10/2004. Last modification: 8/2004.