/* setver.c  -  sets system variables for version numbering
 *	Copyright (C) 2001 Stefan Bellon <sbellon@sbellon.de>
 *
 * This file is part of GnuPG for RISC OS. It is used to set variables
 * for building either the development or release version of GnuPG.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "swis.h"

#define MAXLINELEN 256

static char *filename = NULL;
static const char *start = NULL;
static const char *end = NULL;

static const char *version_start = "m4_define([my_version], [";
static const char *version_end   = "])";
static const char *devel_start   = "m4_define([my_issvn], [";
static const char *devel_end     = "])";

void usage(void)
{
    printf("Syntax: *SetVer <filename> { dist | dev }\n");
    exit(1);
}

void error(char *s)
{
    printf("Error from setver: %s!\n", s);
    exit(2);
}

/* implementation as suggested by Stewart Brodie */
char *strdup(const char *a)
{
    if (a == NULL) {
        return NULL;
    } else {
        const size_t length = strlen(a) + 1;
        char *const p = malloc(length);

        if (p == NULL) return NULL;
        return memcpy(p, a, length);
    }
}

char *read_value(void)
{
    FILE *f;
    int pos = 0;
    char *s, *c;

    f = fopen(filename, "r");

    if (!f)
        error("Couldn't open file for reading");

    while (!feof(f)) {
        if ((char) fgetc(f) == start[pos]) {
            ++pos;
            if (pos >= strlen(start)) {
                s = malloc(MAXLINELEN);
                if (!s)
                    error("Couldn't allocate memory");
                if (!fgets(s, MAXLINELEN, f)) {
                    break;
                } else {
                    if (c = strstr(s, end))
                        *c = 0;
                    return s;
                }
            }
        } else {
            pos = 0;
        }
    }

    fclose(f);

    return "ERROR";
}

char *riscosify(const char *s)
{
    char *i, *sv = strdup(s);
    
    for (i=sv; *i; ++i)
        if (*i == '.')
            *i = '/';
        else if (*i == '/')
            *i = '.';
    
    return sv;
}

char *dist_build(char *v)
{
    int i;
    FILE *f;
    char *t;

    f = fopen("BUILD", "r");
    if (!f)
        error("Couldn't open file 'BUILD' for reading");

    if (fscanf(f, "%i\n", &i) == EOF) {
        fclose(f);
        error("Couldn't read from file 'BUILD'");
    }
    fclose(f);

    f = fopen("BUILD", "w");
    if (!f)
        error("Couldn't open file 'BUILD' for writing");

    if (fprintf(f, "%i\n", ++i) <= 0) {
        fclose(f);
        error("Couldn't write to file 'BUILD'");
    }
    fclose(f);

    t = malloc(16);
    if (!t)
        error("Couldn't allocate memory");

    sprintf(t, "%i", i);

    strcat(v, "-sb");
    strcat(v, t);

    free(t);

    return v;
}

char *dev_build(char *v)
{
    unsigned char utc[5];
    char buf[10];

    utc[0] = 3;
    _kernel_osword(14, (int *) utc);

    if (_swix(Territory_ConvertDateAndTime,
              _INR(0,4),

              -1,
              utc,
              buf,
              sizeof(buf),
              "%CE%YR%MN%DY"))
        error("Couldn't convert date and time");

    strcat(v, "-");
    strcat(v, buf);

    return v;
}

int set(char *s, char *sv, int dev)
{
    char DevDefine[] = "-UIS_DEVELOPMENT_VERSION";

    if (_swix(OS_SetVarVal,
              _INR(0,4),

              "GnuPG$Version",
              s,
              strlen(s),
              0,
              0)) {
        error("Couldn't set variable 'GnuPG$Version'");
    }

    free(s);

    if (_swix(OS_SetVarVal,
              _INR(0,4),

              "GnuPG$SafeVersion",
              sv,
              strlen(sv),
              0,
              0)) {
        error("Couldn't set variable 'GnuPG$SafeVersion'");
    }

    free(sv);

    if (dev)
        DevDefine[1] = 'D';

    if (_swix(OS_SetVarVal,
              _INR(0,4),

              "GnuPG$DevDefine",
              DevDefine,
              strlen(DevDefine),
              0,
              0))
        error("Couldn't set variable 'GnuPG$DevDefine'");

    return 0;
}

int main(int argc, char **argv)
{
    char *v, *sv;

    if (argc != 3)
        usage();
    
    filename = strdup(argv[1]);

    start = version_start;
    end = version_end;
    v = read_value();
    sv = riscosify(v);
    
    start = devel_start;
    end = devel_end;
    if (!strcmp(read_value(), "yes"))
        v = strcat(v, "-svn");

    if (!strcmp(argv[2], "dev"))
        set(dev_build(v), sv, 1);
    else if (!strcmp(argv[2], "dist"))
        set(dist_build(v), sv, 0);

    free(filename);

    return 0;
}
