pre-inst/post.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Jul 15 16:04:47 2020 +0100 (2020-07-15)
changeset 98 71127797ca73
child 99 0121592e2512
permissions -rw-r--r--
app-manager --update and --setup are documented to take URIs but they are not treated as such
ali@96
     1
/*
ali@96
     2
 * Copyright (C) 2020  J. Ali Harlow <ali@juiblex.co.uk>
ali@96
     3
 *
ali@96
     4
 * This program is free software; you can redistribute it and/or modify
ali@96
     5
 * it under the terms of the GNU General Public License as published by
ali@96
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@96
     7
 * (at your option) any later version.
ali@96
     8
 *
ali@96
     9
 * This program is distributed in the hope that it will be useful,
ali@96
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@96
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@96
    12
 * GNU General Public License for more details.
ali@96
    13
 *
ali@96
    14
 * You should have received a copy of the GNU General Public License along
ali@96
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@96
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@96
    17
 */
ali@96
    18
ali@96
    19
#include <string.h>
ali@96
    20
#include <glib.h>
ali@96
    21
#include <expat.h>
ali@96
    22
#include <razor.h>
ali@96
    23
#include <plover/plover.h>
ali@96
    24
#include "pre-inst/post.h"
ali@96
    25
ali@96
    26
#define PLOVER_XML_NS "http://project.juiblex.co.uk/plover/ns/2009"
ali@96
    27
ali@96
    28
enum post_state {
ali@96
    29
    POST_STATE_BEGIN,
ali@96
    30
    POST_STATE_ROOT,
ali@96
    31
    POST_STATE_ARGUMENT,
ali@96
    32
    POST_STATE_INSTALL_PREFIX,
ali@96
    33
    POST_STATE_REPOSITORY,
ali@96
    34
};
ali@96
    35
ali@96
    36
struct post_context {
ali@96
    37
    struct post *post;
ali@96
    38
    enum post_state state;
ali@96
    39
    int unknown_elements;
ali@96
    40
    GPtrArray *args;
ali@96
    41
    GString *str;
ali@96
    42
};
ali@96
    43
ali@96
    44
static void post_start_element(void *data,const char *name,const char **atts)
ali@96
    45
{
ali@96
    46
    struct post_context *ctx=data;
ali@96
    47
    if (ctx->unknown_elements)
ali@96
    48
	ctx->unknown_elements++;
ali@96
    49
    else if (ctx->state==POST_STATE_BEGIN &&
ali@96
    50
      !strcmp(name,PLOVER_XML_NS "\xFF" "post"))
ali@96
    51
	ctx->state=POST_STATE_ROOT;
ali@96
    52
    else if (ctx->state==POST_STATE_ROOT &&
ali@96
    53
      !strcmp(name,PLOVER_XML_NS "\xFF" "command"))
ali@96
    54
    {
ali@96
    55
	ctx->state=POST_STATE_ARGUMENT;
ali@96
    56
	if (ctx->args->len>0)
ali@96
    57
	{
ali@96
    58
	    ctx->str=g_ptr_array_index(ctx->args,0);
ali@96
    59
	    g_string_truncate(ctx->str,0);
ali@96
    60
	}
ali@96
    61
	else
ali@96
    62
	{
ali@96
    63
	    ctx->str=g_string_new(NULL);
ali@96
    64
	    g_ptr_array_add(ctx->args,ctx->str);
ali@96
    65
	}
ali@96
    66
    }
ali@96
    67
    else if (ctx->state==POST_STATE_ROOT &&
ali@96
    68
      !strcmp(name,PLOVER_XML_NS "\xFF" "argument"))
ali@96
    69
    {
ali@96
    70
	ctx->state=POST_STATE_ARGUMENT;
ali@96
    71
	ctx->str=g_string_new(NULL);
ali@96
    72
	if (ctx->args->len==0)
ali@96
    73
	    g_ptr_array_add(ctx->args,NULL);
ali@96
    74
	g_ptr_array_add(ctx->args,ctx->str);
ali@96
    75
    }
ali@96
    76
    else if (ctx->state==POST_STATE_ARGUMENT)
ali@96
    77
    {
ali@96
    78
	if (!strcmp(name,PLOVER_XML_NS "\xFF" "install-prefix"))
ali@96
    79
	    ctx->state=POST_STATE_INSTALL_PREFIX;
ali@96
    80
	else if (!strcmp(name,PLOVER_XML_NS "\xFF" "repository"))
ali@96
    81
	    ctx->state=POST_STATE_REPOSITORY;
ali@96
    82
	else
ali@96
    83
	    ctx->unknown_elements++;
ali@96
    84
    }
ali@96
    85
    else
ali@96
    86
	ctx->unknown_elements++;
ali@96
    87
}
ali@96
    88
ali@96
    89
static void post_end_element(void *data,const char *name)
ali@96
    90
{
ali@96
    91
    struct post_context *ctx=data;
ali@96
    92
    if (ctx->unknown_elements)
ali@96
    93
	ctx->unknown_elements--;
ali@96
    94
    else
ali@96
    95
	switch (ctx->state)
ali@96
    96
	{
ali@96
    97
	    case POST_STATE_ROOT:
ali@96
    98
		ctx->state=POST_STATE_BEGIN;
ali@96
    99
		break;
ali@96
   100
	    case POST_STATE_ARGUMENT:
ali@96
   101
		ctx->state=POST_STATE_ROOT;
ali@96
   102
		break;
ali@96
   103
	    case POST_STATE_INSTALL_PREFIX:
ali@96
   104
		if (ctx->post->install_prefix)
ali@96
   105
		    g_string_append(ctx->str,ctx->post->install_prefix);
ali@96
   106
		ctx->state=POST_STATE_ARGUMENT;
ali@96
   107
		break;
ali@96
   108
	    case POST_STATE_REPOSITORY:
ali@96
   109
		if (ctx->post->repository)
ali@96
   110
		    g_string_append(ctx->str,ctx->post->repository);
ali@96
   111
		ctx->state=POST_STATE_ARGUMENT;
ali@96
   112
		break;
ali@96
   113
	}
ali@96
   114
}
ali@96
   115
ali@96
   116
static void post_character_data(void *data,const XML_Char *s,int len)
ali@96
   117
{
ali@96
   118
    struct post_context *ctx=data;
ali@96
   119
    switch (ctx->state)
ali@96
   120
    {
ali@96
   121
	case POST_STATE_ARGUMENT:
ali@96
   122
	    g_string_append_len(ctx->str,s,len);
ali@96
   123
	    break;
ali@96
   124
    }
ali@96
   125
}
ali@96
   126
ali@96
   127
struct post *pre_install_post_new(const char *repository,
ali@96
   128
  const char *install_prefix)
ali@96
   129
{
ali@96
   130
    struct post *post;
ali@96
   131
    post=g_new0(struct post,1);
ali@96
   132
    post->repository=g_strdup(repository);
ali@96
   133
    post->install_prefix=g_strdup(install_prefix);
ali@96
   134
    return post;
ali@96
   135
}
ali@96
   136
ali@96
   137
void pre_install_post_free(struct post *post)
ali@96
   138
{
ali@96
   139
    g_free(post->repository);
ali@96
   140
    g_free(post->install_prefix);
ali@96
   141
    g_free(post);
ali@96
   142
}
ali@96
   143
ali@96
   144
gboolean pre_install_post_load_uri(struct post *post,const char *uri,
ali@96
   145
  GError **error)
ali@96
   146
{
ali@96
   147
    int i;
ali@96
   148
    gboolean retval;
ali@96
   149
    struct post_context ctx={0,};
ali@96
   150
    struct razor_error *tmp_error=NULL;
ali@96
   151
    size_t length;
ali@96
   152
    void *contents;
ali@96
   153
    XML_Parser parser;
ali@96
   154
    contents=razor_uri_get_contents(uri,&length,FALSE,&tmp_error);
ali@96
   155
    if (!contents)
ali@96
   156
    {
ali@96
   157
	plover_propagate_razor_error(error,tmp_error);
ali@96
   158
	return FALSE;
ali@96
   159
    }
ali@96
   160
    parser=XML_ParserCreateNS(NULL,'\xFF');
ali@96
   161
    ctx.post=post;
ali@96
   162
    ctx.state=POST_STATE_BEGIN;
ali@96
   163
    ctx.args=g_ptr_array_new();
ali@96
   164
    XML_SetUserData(parser,&ctx);
ali@96
   165
    XML_SetElementHandler(parser,post_start_element,post_end_element);
ali@96
   166
    XML_SetCharacterDataHandler(parser,post_character_data);
ali@96
   167
    retval=XML_Parse(parser,contents,length,TRUE)!=XML_STATUS_ERROR;
ali@96
   168
    if (!retval)
ali@96
   169
	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
ali@96
   170
	  "%s on line %d of '%s'\n",
ali@96
   171
	  XML_ErrorString(XML_GetErrorCode(parser)),
ali@96
   172
	  XML_GetCurrentLineNumber(parser),uri);
ali@96
   173
    XML_ParserFree(parser);
ali@96
   174
    razor_uri_free_contents(contents,length);
ali@96
   175
    if (retval)
ali@96
   176
    {
ali@96
   177
	if (ctx.args->len>0 && !g_ptr_array_index(ctx.args,0))
ali@96
   178
	    g_warning("post: ignoring arguments because no command specified");
ali@96
   179
	if (post->argv)
ali@96
   180
	    g_strfreev(post->argv);
ali@96
   181
	if (ctx.args->len>0 && g_ptr_array_index(ctx.args,0))
ali@96
   182
	{
ali@96
   183
	    post->argc=ctx.args->len;
ali@96
   184
	    post->argv=g_new(gchar *,post->argc+1);
ali@96
   185
	    for(i=0;i<post->argc;i++)
ali@96
   186
		post->argv[i]=
ali@96
   187
		  g_string_free(g_ptr_array_index(ctx.args,i),FALSE);
ali@96
   188
	    post->argv[i]=NULL;
ali@96
   189
	}
ali@96
   190
	else
ali@96
   191
	{
ali@96
   192
	    post->argc=0;
ali@96
   193
	    post->argv=g_new0(gchar *,1);
ali@96
   194
	}
ali@96
   195
	g_ptr_array_free(ctx.args,FALSE);
ali@96
   196
    }
ali@96
   197
    return retval;
ali@96
   198
}