1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Form parameters
29  *
30  */
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ipxe/params.h>
35 
36 /** List of all parameter lists */
37 static LIST_HEAD ( parameters );
38 
39 /**
40  * Free form parameter list
41  *
42  * @v refcnt		Reference count
43  */
free_parameters(struct refcnt * refcnt)44 static void free_parameters ( struct refcnt *refcnt ) {
45 	struct parameters *params =
46 		container_of ( refcnt, struct parameters, refcnt );
47 	struct parameter *param;
48 	struct parameter *tmp;
49 
50 	DBGC ( params, "PARAMS \"%s\" destroyed\n", params->name );
51 
52 	/* Free all parameters */
53 	list_for_each_entry_safe ( param, tmp, &params->entries, list ) {
54 		list_del ( &param->list );
55 		free ( param );
56 	}
57 
58 	/* Free parameter list */
59 	free ( params );
60 }
61 
62 /**
63  * Find form parameter list by name
64  *
65  * @v name		Parameter list name (may be NULL)
66  * @ret params		Parameter list, or NULL if not found
67  */
find_parameters(const char * name)68 struct parameters * find_parameters ( const char *name ) {
69 	struct parameters *params;
70 
71 	list_for_each_entry ( params, &parameters, list ) {
72 		if ( ( params->name == name ) ||
73 		     ( strcmp ( params->name, name ) == 0 ) ) {
74 			return params;
75 		}
76 	}
77 	return NULL;
78 }
79 
80 /**
81  * Create form parameter list
82  *
83  * @v name		Parameter list name (may be NULL)
84  * @ret params		Parameter list, or NULL on failure
85  */
create_parameters(const char * name)86 struct parameters * create_parameters ( const char *name ) {
87 	struct parameters *params;
88 	size_t name_len;
89 	char *name_copy;
90 
91 	/* Destroy any existing parameter list of this name */
92 	params = find_parameters ( name );
93 	if ( params ) {
94 		claim_parameters ( params );
95 		params_put ( params );
96 	}
97 
98 	/* Allocate parameter list */
99 	name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
100 	params = zalloc ( sizeof ( *params ) + name_len );
101 	if ( ! params )
102 		return NULL;
103 	ref_init ( &params->refcnt, free_parameters );
104 	name_copy = ( ( void * ) ( params + 1 ) );
105 
106 	/* Populate parameter list */
107 	if ( name ) {
108 		strcpy ( name_copy, name );
109 		params->name = name_copy;
110 	}
111 	INIT_LIST_HEAD ( &params->entries );
112 
113 	/* Add to list of parameter lists */
114 	list_add_tail ( &params->list, &parameters );
115 
116 	DBGC ( params, "PARAMS \"%s\" created\n", params->name );
117 	return params;
118 }
119 
120 /**
121  * Add form parameter
122  *
123  * @v params		Parameter list
124  * @v key		Parameter key
125  * @v value		Parameter value
126  * @ret param		Parameter, or NULL on failure
127  */
add_parameter(struct parameters * params,const char * key,const char * value)128 struct parameter * add_parameter ( struct parameters *params,
129 				   const char *key, const char *value ) {
130 	struct parameter *param;
131 	size_t key_len;
132 	size_t value_len;
133 	char *key_copy;
134 	char *value_copy;
135 
136 	/* Allocate parameter */
137 	key_len = ( strlen ( key ) + 1 /* NUL */ );
138 	value_len = ( strlen ( value ) + 1 /* NUL */ );
139 	param = zalloc ( sizeof ( *param ) + key_len + value_len );
140 	if ( ! param )
141 		return NULL;
142 	key_copy = ( ( void * ) ( param + 1 ) );
143 	value_copy = ( key_copy + key_len );
144 
145 	/* Populate parameter */
146 	strcpy ( key_copy, key );
147 	param->key = key_copy;
148 	strcpy ( value_copy, value );
149 	param->value = value_copy;
150 
151 	/* Add to list of parameters */
152 	list_add_tail ( &param->list, &params->entries );
153 
154 	DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
155 	       params->name, param->key, param->value );
156 	return param;
157 }
158