/*
* Originally count.c, by Chris Stephens, stephenc@pcmail.cbil.vcu.edu, (c)1995.
*
* Code cleaned up and enhanced by Fred Christiansen, fredch@fc.hp.com,
* as odometer.c; supports:
* - 8 digits instead of 7 (and by changing ODO_DIGITS, up to 10 (number
* of digits in an unsigned long))
* - acceptance of an argument to create a distinct counter file name; this
* permits refs like when
* used in combination with Ksh script odometer.cgi:
* exec ./odometer $QUERY_STRING
*
* Code cleaned up and enhanced a little more by Francois Planque,
* fplanque@planete.net in March 1996; supports:
* - sends out plain text error messages for debugging. These work when
* you reference the counter directly from your browser, i-e when
* you don't reference it in an tag.
*/
#include
#include
#include
/*
* Definition des images des chiffres:
*/
char *bitmap[] = {
"0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0x99", /* rows 1-8 of 0 */
"0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff", /* rows 9-16 of 0 */
"0xff","0xff","0xff","0xcf","0xc7","0xcf","0xcf","0xcf", /* rows 1-8 of 1 */
"0xcf","0xcf","0xcf","0xcf","0xcf","0xff","0xff","0xff", /* rows 9-16 of 1 */
"0xff","0xff","0xff","0xc3","0x99","0x9f","0x9f","0xcf", /* rows 1-8 of 2 */
"0xe7","0xf3","0xf9","0xf9","0x81","0xff","0xff","0xff", /* rows 9-16 of 2 */
"0xff","0xff","0xff","0xc3","0x99","0x9f","0x9f","0xc7", /* rows 1-8 of 3 */
"0x9f","0x9f","0x9f","0x99","0xc3","0xff","0xff","0xff", /* rows 9-16 of 3 */
"0xff","0xff","0xff","0xcf","0xcf","0xc7","0xc7","0xcb", /* rows 1-8 of 4 */
"0xcb","0xcd","0x81","0xcf","0x87","0xff","0xff","0xff", /* rows 9-16 of 4 */
"0xff","0xff","0xff","0x81","0xf9","0xf9","0xf9","0xc1", /* rows 1-8 of 5 */
"0x9f","0x9f","0x9f","0x99","0xc3","0xff","0xff","0xff", /* rows 9-16 of 5 */
"0xff","0xff","0xff","0xc7","0xf3","0xf9","0xf9","0xc1", /* rows 1-8 of 6 */
"0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff", /* rows 9-16 of 6 */
"0xff","0xff","0xff","0x81","0x99","0x9f","0x9f","0xcf", /* rows 1-8 of 7 */
"0xcf","0xe7","0xe7","0xf3","0xf3","0xff","0xff","0xff", /* rows 9-16 of 7 */
"0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0xc3", /* rows 1-8 of 8 */
"0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff", /* rows 9-16 of 8 */
"0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0x99", /* rows 1-8 of 9 */
"0x83","0x9f","0x9f","0xcf","0xe3","0xff","0xff","0xff" /* rows 9-16 of 9 */
};
/*
* Chemin d'acces au fichier qui garde la valeur courante du compteur:
* Etant donne le id sous lequel les scripts CGI s'executent,
* ls permissions de ce fichier doivent etre 666:
*/
#define ODO_FILE "/usr/home/fplanque/public_html/.odo%s" /* prime w/ 1 */
#define UPDATE "r+"
#define NL '\n' /* new line char */
#define ODO_DIGITS 8 /* Nombre de chiffres a afficher */
#define BUFSIZE (ODO_DIGITS+2) /* 8 digits + NL + nul */
#define BM_HT 16 /* bitmap height */
#define BM_WD 8 /* bitmap width */
main(int argc, char *argv[])
{
FILE *fp;
char path[64], buf[BUFSIZE], dial[ODO_DIGITS];
unsigned long cnt;
int i, l;
char *p;
/*
* Verification des arguments:
*/
if (argc != 2)
{ /*
* Nombre d'arguments incorrect:
* Affiche msg d'erreur et quitte:
*/
printf( "Content-type: text/plain\n\n" );
printf( "Odometer:\n" );
printf( " Je n'ai pas recu de nom de compteur en argument.\n" );
printf( " Essayez de m'appeler de la maniere suivante: http://.../cgi-bin/odometer?nom_compteur\n" );
exit(0);
}
/*
* Creation du nom de fichier du compteur en fonction du nom passe en argument:
*/
sprintf(path, ODO_FILE, argv[1]);
/*
* ---------------------------------
* Manipulation du fichier compteur:
* ---------------------------------
* Ouverture du fichier compteur:
*/
if ((fp = fopen(path, UPDATE)) == NULL)
{
printf( "Content-type: text/plain\n\n" );
printf( "Odometer:\n" );
printf( " Impossible d'ouvrir le fichier compteur: %s\n", path );
printf( " Verifiez que ce fichier existe, sinon creez le en y inscrivant "
"le chiffre 0 et un retour chariot.\n" );
printf( " S'il existe, verifiez que les permissions sont 666. "
"Au besoin faites un chmod 666 .odo*\n" );
exit(0);
}
/*
* File-LOCK:
* S'assure que personne d'autre n'est en train d'ecrire dans ce fichier,
* sinon: attend que l'autre ait termine:
*/
flock(fileno(fp), LOCK_EX);
/*
* Lecture du compteur actuel:
*/
fgets(buf, BUFSIZE, fp);
/*
* Conversion de la chaine de caracteres lue en entier:
*/
cnt = strtoul(buf, (char **)NULL, 10);
/*
* Incrementation:
*/
cnt++;
/*
* Retourne au debut du fichier en vue d'y ecrire la nouvelle valeur du compteur:
*/
rewind(fp);
/*
* Ecriture de la nouvelle valeur dans le fichier:
*/
fprintf(fp, "%u\n", cnt);
/*
* Fermeture du fichier:
*/
fclose(fp);
/*
* -----------------------------------------
* Creation et envoi de l'image du compteur:
* -----------------------------------------
* Calcul de la longueur et copie de droite a gauche dans dial[]:
*/
for(l = 0, p = buf; *p != NL; l++, p++)
;
for (i = 0, p = buf; i < l; i++, p++)
dial[ODO_DIGITS - l + i] = *p;
for (i = 0; i < (ODO_DIGITS - l); i++) /* backfill with zeros */
dial[i] = '0';
/*
* Envoi du header HTTP et de la definition XBM:
*/
printf("Content-type: image/x-xbitmap\n\n");
printf("#define odo_width %d\n", (BM_WD*ODO_DIGITS));
printf("#define odo_height %d\n", BM_HT);
printf("static char odo_bits[] = {\n");
for (i = 0; i < BM_HT; i++)
{
for (l = 0; l < ODO_DIGITS; l++)
{
printf("%s, ", bitmap[(((dial[l]-'0')*BM_HT)+i)]);
if (l == 7)
printf("\n");
}
if (i == 15)
printf("};");
}
printf("\n");
exit(0);
}