pre-inst/post.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Aug 31 07:07:40 2020 +0100 (2020-08-31)
changeset 103 c4b0d5cc34bc
parent 96 d2d88f14283e
permissions -rw-r--r--
Add support for --default-action in app-manager
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@99
    19
#include "config.h"
ali@96
    20
#include <string.h>
ali@96
    21
#include <glib.h>
ali@96
    22
#include <expat.h>
ali@96
    23
#include <razor.h>
ali@96
    24
#include <plover/plover.h>
ali@96
    25
#include "pre-inst/post.h"
ali@96
    26
ali@96
    27
#define PLOVER_XML_NS "http://project.juiblex.co.uk/plover/ns/2009"
ali@96
    28
ali@96
    29
enum post_state {
ali@96
    30
    POST_STATE_BEGIN,
ali@96
    31
    POST_STATE_ROOT,
ali@96
    32
    POST_STATE_ARGUMENT,
ali@96
    33
    POST_STATE_INSTALL_PREFIX,
ali@96
    34
    POST_STATE_REPOSITORY,
ali@96
    35
};
ali@96
    36
ali@96
    37
struct post_context {
ali@96
    38
    struct post *post;
ali@96
    39
    enum post_state state;
ali@96
    40
    int unknown_elements;
ali@96
    41
    GPtrArray *args;
ali@96
    42
    GString *str;
ali@96
    43
};
ali@96
    44
ali@96
    45
static void post_start_element(void *data,const char *name,const char **atts)
ali@96
    46
{
ali@96
    47
    struct post_context *ctx=data;
ali@96
    48
    if (ctx->unknown_elements)
ali@96
    49
	ctx->unknown_elements++;
ali@96
    50
    else if (ctx->state==POST_STATE_BEGIN &&
ali@96
    51
      !strcmp(name,PLOVER_XML_NS "\xFF" "post"))
ali@96
    52
	ctx->state=POST_STATE_ROOT;
ali@96
    53
    else if (ctx->state==POST_STATE_ROOT &&
ali@96
    54
      !strcmp(name,PLOVER_XML_NS "\xFF" "command"))
ali@96
    55
    {
ali@96
    56
	ctx->state=POST_STATE_ARGUMENT;
ali@96
    57
	if (ctx->args->len>0)
ali@96
    58
	{
ali@96
    59
	    ctx->str=g_ptr_array_index(ctx->args,0);
ali@96
    60
	    g_string_truncate(ctx->str,0);
ali@96
    61
	}
ali@96
    62
	else
ali@96
    63
	{
ali@96
    64
	    ctx->str=g_string_new(NULL);
ali@96
    65
	    g_ptr_array_add(ctx->args,ctx->str);
ali@96
    66
	}
ali@96
    67
    }
ali@96
    68
    else if (ctx->state==POST_STATE_ROOT &&
ali@96
    69
      !strcmp(name,PLOVER_XML_NS "\xFF" "argument"))
ali@96
    70
    {
ali@96
    71
	ctx->state=POST_STATE_ARGUMENT;
ali@96
    72
	ctx->str=g_string_new(NULL);
ali@96
    73
	if (ctx->args->len==0)
ali@96
    74
	    g_ptr_array_add(ctx->args,NULL);
ali@96
    75
	g_ptr_array_add(ctx->args,ctx->str);
ali@96
    76
    }
ali@96
    77
    else if (ctx->state==POST_STATE_ARGUMENT)
ali@96
    78
    {
ali@96
    79
	if (!strcmp(name,PLOVER_XML_NS "\xFF" "install-prefix"))
ali@96
    80
	    ctx->state=POST_STATE_INSTALL_PREFIX;
ali@96
    81
	else if (!strcmp(name,PLOVER_XML_NS "\xFF" "repository"))
ali@96
    82
	    ctx->state=POST_STATE_REPOSITORY;
ali@96
    83
	else
ali@96
    84
	    ctx->unknown_elements++;
ali@96
    85
    }
ali@96
    86
    else
ali@96
    87
	ctx->unknown_elements++;
ali@96
    88
}
ali@96
    89
ali@96
    90
static void post_end_element(void *data,const char *name)
ali@96
    91
{
ali@96
    92
    struct post_context *ctx=data;
ali@96
    93
    if (ctx->unknown_elements)
ali@96
    94
	ctx->unknown_elements--;
ali@96
    95
    else
ali@96
    96
	switch (ctx->state)
ali@96
    97
	{
ali@99
    98
	    case POST_STATE_BEGIN:
ali@99
    99
		g_assert_not_reached();
ali@99
   100
		break;
ali@96
   101
	    case POST_STATE_ROOT:
ali@96
   102
		ctx->state=POST_STATE_BEGIN;
ali@96
   103
		break;
ali@96
   104
	    case POST_STATE_ARGUMENT:
ali@96
   105
		ctx->state=POST_STATE_ROOT;
ali@96
   106
		break;
ali@96
   107
	    case POST_STATE_INSTALL_PREFIX:
ali@96
   108
		if (ctx->post->install_prefix)
ali@96
   109
		    g_string_append(ctx->str,ctx->post->install_prefix);
ali@96
   110
		ctx->state=POST_STATE_ARGUMENT;
ali@96
   111
		break;
ali@96
   112
	    case POST_STATE_REPOSITORY:
ali@96
   113
		if (ctx->post->repository)
ali@96
   114
		    g_string_append(ctx->str,ctx->post->repository);
ali@96
   115
		ctx->state=POST_STATE_ARGUMENT;
ali@96
   116
		break;
ali@96
   117
	}
ali@96
   118
}
ali@96
   119
ali@96
   120
static void post_character_data(void *data,const XML_Char *s,int len)
ali@96
   121
{
ali@96
   122
    struct post_context *ctx=data;
ali@96
   123
    switch (ctx->state)
ali@96
   124
    {
ali@96
   125
	case POST_STATE_ARGUMENT:
ali@96
   126
	    g_string_append_len(ctx->str,s,len);
ali@96
   127
	    break;
ali@99
   128
	default:
ali@99
   129
	    break;
ali@96
   130
    }
ali@96
   131
}
ali@96
   132
ali@96
   133
struct post *pre_install_post_new(const char *repository,
ali@96
   134
  const char *install_prefix)
ali@96
   135
{
ali@96
   136
    struct post *post;
ali@96
   137
    post=g_new0(struct post,1);
ali@96
   138
    post->repository=g_strdup(repository);
ali@96
   139
    post->install_prefix=g_strdup(install_prefix);
ali@96
   140
    return post;
ali@96
   141
}
ali@96
   142
ali@96
   143
void pre_install_post_free(struct post *post)
ali@96
   144
{
ali@96
   145
    g_free(post->repository);
ali@96
   146
    g_free(post->install_prefix);
ali@96
   147
    g_free(post);
ali@96
   148
}
ali@96
   149
ali@96
   150
gboolean pre_install_post_load_uri(struct post *post,const char *uri,
ali@96
   151
  GError **error)
ali@96
   152
{
ali@96
   153
    int i;
ali@96
   154
    gboolean retval;
ali@96
   155
    struct post_context ctx={0,};
ali@96
   156
    struct razor_error *tmp_error=NULL;
ali@96
   157
    size_t length;
ali@96
   158
    void *contents;
ali@96
   159
    XML_Parser parser;
ali@96
   160
    contents=razor_uri_get_contents(uri,&length,FALSE,&tmp_error);
ali@96
   161
    if (!contents)
ali@96
   162
    {
ali@96
   163
	plover_propagate_razor_error(error,tmp_error);
ali@96
   164
	return FALSE;
ali@96
   165
    }
ali@96
   166
    parser=XML_ParserCreateNS(NULL,'\xFF');
ali@96
   167
    ctx.post=post;
ali@96
   168
    ctx.state=POST_STATE_BEGIN;
ali@96
   169
    ctx.args=g_ptr_array_new();
ali@96
   170
    XML_SetUserData(parser,&ctx);
ali@96
   171
    XML_SetElementHandler(parser,post_start_element,post_end_element);
ali@96
   172
    XML_SetCharacterDataHandler(parser,post_character_data);
ali@96
   173
    retval=XML_Parse(parser,contents,length,TRUE)!=XML_STATUS_ERROR;
ali@96
   174
    if (!retval)
ali@96
   175
	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
ali@99
   176
	  "%s on line %lu of '%s'\n",
ali@96
   177
	  XML_ErrorString(XML_GetErrorCode(parser)),
ali@99
   178
	  (unsigned long)XML_GetCurrentLineNumber(parser),uri);
ali@96
   179
    XML_ParserFree(parser);
ali@96
   180
    razor_uri_free_contents(contents,length);
ali@96
   181
    if (retval)
ali@96
   182
    {
ali@96
   183
	if (ctx.args->len>0 && !g_ptr_array_index(ctx.args,0))
ali@96
   184
	    g_warning("post: ignoring arguments because no command specified");
ali@96
   185
	if (post->argv)
ali@96
   186
	    g_strfreev(post->argv);
ali@96
   187
	if (ctx.args->len>0 && g_ptr_array_index(ctx.args,0))
ali@96
   188
	{
ali@96
   189
	    post->argc=ctx.args->len;
ali@96
   190
	    post->argv=g_new(gchar *,post->argc+1);
ali@96
   191
	    for(i=0;i<post->argc;i++)
ali@96
   192
		post->argv[i]=
ali@96
   193
		  g_string_free(g_ptr_array_index(ctx.args,i),FALSE);
ali@96
   194
	    post->argv[i]=NULL;
ali@96
   195
	}
ali@96
   196
	else
ali@96
   197
	{
ali@96
   198
	    post->argc=0;
ali@96
   199
	    post->argv=g_new0(gchar *,1);
ali@96
   200
	}
ali@96
   201
	g_ptr_array_free(ctx.args,FALSE);
ali@96
   202
    }
ali@96
   203
    return retval;
ali@96
   204
}