1 /*
2  *                           TERMS AND CONDITIONS
3  *                                   FOR
4  *                         OPEN SOURCE CODE LICENSE
5  *                               Version 1.1
6  *
7  * Japan Registry Services Co., Ltd. ("JPRS"), a Japanese corporation
8  * having its head office at Chiyoda First Bldg. East 13F 3-8-1 Nishi-Kanda,
9  * Chiyoda-ku, Tokyo 101-0065, Japan, grants you the license for open source
10  * code specified in EXHIBIT A the "Code" subject to the following Terms and
11  * Conditions ("OSCL").
12  *
13  * 1. License Grant.
14  *   JPRS hereby grants you a worldwide, royalty-free, non-exclusive
15  *   license, subject to third party intellectual property claims:
16  *   (a) under intellectual property rights (other than patent or
17  *       trademark) licensable by JPRS to use, reproduce, modify, display,
18  *       perform, sublicense and distribute the Code (or portions thereof)
19  *       with or without modifications, and/or as part of a derivative work;
20  *       or
21  *   (b) under claims of the infringement through the making, using,
22  *       offering to sell and/or otherwise disposing the JPRS Revised Code
23  *       (or portions thereof);
24  *   (c) the licenses granted in this Section 1(a) and (b) are effective on
25  *       the date JPRS first distributes the Code to you under the terms of
26  *       this OSCL;
27  *   (d) Notwithstanding the above stated terms, no patent license is
28  *       granted:
29  *       1)  for a code that you delete from the Code;
30  *       2)  separate from the Code; or
31  *       3)  for infringements caused by:
32  *            i) modification of the Code; or
33  *           ii) combination of the Code with other software or devices.
34  *
35  * 2. Consents.
36  *   You agree that:
37  *   (a) you must include a copy of this OSCL and the notice set forth in
38  *       EXHIBIT A with every copy of the Code you distribute;
39  *   (b) you must include a copy of this OSCL and the notice set forth in
40  *       EXHIBIT A with every copy of binary form of the Code in the
41  *       documentation and/or other materials provided with the distribution;
42  *   (c) you may not offer or impose any terms on any source code version
43  *       that alters or restricts the applicable version of this OSCL or
44  *       the recipients' rights hereunder.
45  *   (d) If the terms and conditions are set forth in EXHIBIT A, you must
46  *       comply with those terms and conditions.
47  *
48  * 3. Proprietary Information.
49  *   All trademarks, service marks, patents, copyrights, trade secrets, and
50  *   other proprietary rights in or related to the Code are and will remain
51  *   the exclusive property of JPRS or its licensors, whether or not
52  *   specifically recognized or perfected under local law except specified
53  *   in this OSCL; provided however you agree and understand that the JPRS
54  *   name may not be used to endorse or promote this Code without prior
55  *   written approval of JPRS.
56  *
57  * 4. WARRANTY DISCLAIMER.
58  *   JPRS MAKES NO REPRESENTATIONS AND WARRANTIES REGARDING THE USE OF THE
59  *   CODE, NOR DOES JPRS MAKE ANY REPRESENTATIONS THAT THE CODE WILL BECOME
60  *   COMMERCIALLY AVAILABLE. JPRS, ITS AFFILIATES, AND ITS SUPPLIERS DO NOT
61  *   WARRANT OR REPRESENT THAT THE CODE IS FREE OF ERRORS OR THAT THE CODE
62  *   IS SUITABLE FOR TRANSLATION AND/OR LOCALIZATION. THE CODE IS PROVIDED
63  *   ON AN "AS IS" BASIS AND JPRS AND ITS SUPPLIERS HAVE NO OBLIGATION TO
64  *   CORRECT ERRORS OR TO SUPPORT THE CODE UNDER THIS OSCL FOR ANY REASON.
65  *   TO THE FULL EXTENT PERMITTED BY LAW, ALL OBLIGATIONS ARE HEREBY
66  *   EXCLUDED WHETHER EXPRESS, STATUTORY OR IMPLIED UNDER LAW, COURSE OF
67  *   DEALING, CUSTOM, TRADE USAGE, ORAL OR WRITTEN STATEMENT OR OTHERWISE,
68  *   INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY
69  *   OR FITNESS FOR A PARTICULAR PURPOSE CONCERNING THE CODE.
70  *
71  * 5. NO LIABILITY.
72  *   UNDER NO CIRCUMSTANCES SHALL JPRS AND/OR ITS AFFILIATES, LICENSORS, OR
73  *   REPRESENTATIVES BE LIABLE FOR ANY DAMAGES INCLUDING BUT NOT LIMITED TO
74  *   CONSEQUENTIAL, INDIRECT, SPECIAL, PUNITIVE OR INCIDENTAL DAMAGES,
75  *   WHETHER FORESEEABLE OR UNFORESEEABLE, BASED ON YOUR CLAIMS, INCLUDING,
76  *   BUT NOT LIMITED TO, CLAIMS FOR LOSS OF DATA, GOODWILL, PROFITS, USE OF
77  *   MONEY, INTERRUPTION IN USE OR AVAILABILITY OF DATA, STOPPAGE, IMPLIED
78  *   WARRANTY, BREACH OF CONTRACT, MISREPRESENTATION, NEGLIGENCE, STRICT
79  *   LIABILITY IN TORT, OR OTHERWISE.
80  *
81  * 6. Indemnification.
82  *   You hereby agree to indemnify, defend, and hold harmless JPRS for any
83  *   liability incurred by JRPS due to your terms of warranty, support,
84  *   indemnity, or liability offered by you to any third party.
85  *
86  * 7. Termination.
87  * 7.1 This OSCL shall be automatically terminated in the events that:
88  *   (a) You fail to comply with the terms herein and fail to cure such
89  *       breach within 30 days of becoming aware of the breach;
90  *   (b) You initiate patent or copyright infringement litigation against
91  *       any party (including a cross-claim or counterclaim in a lawsuit)
92  *       alleging that the Code constitutes a direct or indirect patent or
93  *       copyright infringement, in such case, this OSCL to you shall
94  *       terminate as of the date such litigation is filed;
95  * 7.2 In the event of termination under Sections 7.1(a) or 7.1(b) above,
96  *     all end user license agreements (excluding distributors and
97  *     resellers) which have been validly granted by You or any distributor
98  *     hereunder prior to termination shall survive termination.
99  *
100  *
101  * 8. General.
102  *   This OSCL shall be governed by, and construed and enforced in
103  *   accordance with, the laws of Japan. Any litigation or arbitration
104  *   between the parties shall be conducted exclusively in Tokyo, Japan
105  *   except written consent of JPRS provides other venue.
106  *
107  *
108  *                                EXHIBIT A
109  *
110  * The original open source code of idnkit-2 is idnkit-1.0 developed and
111  * conceived by Japan Network Information Center ("JPNIC"), a Japanese
112  * association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
113  * Chiyoda-ku, Tokyo 101-0047, Japan, and JPRS modifies above original code
114  * under following Terms and Conditions set forth by JPNIC.
115  *
116  *                                  JPNIC
117  *
118  * Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved.
119  *
120  * By using this file, you agree to the terms and conditions set forth bellow.
121  *
122  *                       LICENSE TERMS AND CONDITIONS
123  *
124  * The following License Terms and Conditions apply, unless a different
125  * license is obtained from Japan Network Information Center ("JPNIC"),
126  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
127  * Chiyoda-ku, Tokyo 101-0047, Japan.
128  *
129  * 1. Use, Modification and Redistribution (including distribution of any
130  *    modified or derived work) in source and/or binary forms is permitted
131  *    under this License Terms and Conditions.
132  *
133  * 2. Redistribution of source code must retain the copyright notices as they
134  *    appear in each source code file, this License Terms and Conditions.
135  *
136  * 3. Redistribution in binary form must reproduce the Copyright Notice,
137  *    this License Terms and Conditions, in the documentation and/or other
138  *    materials provided with the distribution. For the purposes of binary
139  *    distribution the "Copyright Notice" refers to the following language:
140  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
141  *
142  * 4. The name of JPNIC may not be used to endorse or promote products
143  *    derived from this Software without specific prior written approval of
144  *    JPNIC.
145  *
146  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
147  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
148  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
149  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
150  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
151  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
152  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
153  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
154  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
155  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
156  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
157  *
158  *
159  *                        JPRS Public License Notice
160  *                                   For
161  *                                idnkit-2.
162  *
163  * The contents of this file are subject to the Terms and Conditions for
164  * the Open Source Code License (the "OSCL"). You may not use this file
165  * except in compliance with above terms and conditions. A copy of the OSCL
166  * is available at <http://jprs.co.jp/idn/>.
167  * The JPRS Revised Code is idnkit-2.
168  * The Initial Developer of the JPRS Revised Code is Japan Network
169  * Information Center ("JPNIC"), a Japanese association,
170  * Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda, Chiyoda-ku, Tokyo
171  * 101-0047, Japan.
172  * "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
173  * "Copyright (c) 2010-2012 Japan Registry Services Co., Ltd.  All rights reserved."
174  * Contributor(s): ______________________________________.
175  *
176  * If you wish to allow use of your version of this file only under the
177  * above License(s) and not to allow others to use your version of this
178  * file, please indicate your decision by deleting the relevant provisions
179  * above and replacing them with the notice and other provisions required
180  * by the above License(s). If you do not delete the relevant provisions,
181  * a recipient may use your version of this file under either the above
182  * License(s).
183  */
184 
185 #include <config.h>
186 
187 #include <stddef.h>
188 #include <stdlib.h>
189 #include <string.h>
190 
191 #include <idn/assert.h>
192 #include <idn/debug.h>
193 #include <idn/logmacro.h>
194 #include <idn/result.h>
195 #include <idn/labellist.h>
196 #include <idn/utf32.h>
197 
198 struct idn__labellist {
199 	unsigned long *name;		/* name of the label */
200 	unsigned long *undo_name;	/* name for UNDOIFERR */
201 	unsigned long *round_trip_name;	/* name for RTCHECK */
202 	idn__labellist_t next;		/* pointer to the next label */
203 	int dot_followed;		/* followed by '.' or not */
204 	int undo_count;			/* the number of undo times */
205 };
206 
207 idn_result_t
idn__labellist_create(const unsigned long * name,idn__labellist_t * labellist)208 idn__labellist_create(const unsigned long *name,
209 		      idn__labellist_t *labellist) {
210 	idn_result_t r = idn_success;
211 	size_t length;
212 	idn__labellist_t head_label = NULL;
213 	idn__labellist_t tail_label = NULL;
214 	idn__labellist_t new_label = NULL;
215 	const unsigned long *endp = NULL;
216 
217 	assert(name != NULL && labellist != NULL);
218 
219 	TRACE(("idn__labellist_create(name=\"%s\")\n",
220 	       idn__debug_utf32xstring(name)));
221 
222 	while (*name != '\0') {
223 		for (endp = name; *endp != '.' && *endp != '\0'; endp++)
224 			;  /* nothing to be done */
225 		length = endp - name;
226 
227 		new_label = (idn__labellist_t)
228 			    malloc(sizeof(struct idn__labellist));
229 		if (new_label == NULL) {
230 			r = idn_nomemory;
231 			goto ret;
232 		}
233 		if (head_label == NULL)
234 			head_label = new_label;
235 
236 		new_label->name = NULL;
237 		new_label->undo_name = NULL;
238 		new_label->round_trip_name = NULL;
239 		new_label->next = NULL;
240 		new_label->dot_followed = (*endp == '.');
241 		new_label->undo_count = 0;
242 
243 		new_label->name = idn__utf32_strndup(name, length);
244 		if (new_label->name == NULL) {
245 			r = idn_nomemory;
246 			goto ret;
247 		}
248 
249 		if (tail_label != NULL)
250 			tail_label->next = new_label;
251 
252 		tail_label = new_label;
253 
254 		if (*endp == '.')
255 			name = endp + 1;
256 		else
257 			name = endp;
258 	}
259 
260 	*labellist = head_label;
261 
262 ret:
263 	if (r == idn_success)
264 		TRACE(("idn__labellist_create(): success\n"));
265 	else {
266 		TRACE(("idn__labellist_create(): %s\n",
267 		       idn_result_tostring(r)));
268 	}
269 
270 	if (r != idn_success) {
271 		if (new_label != NULL) {
272 			free(new_label->name);
273 			free(new_label->undo_name);
274 			free(new_label->round_trip_name);
275 			free(new_label);
276 		}
277 		if (head_label != NULL)
278 			idn__labellist_destroy(head_label);
279 	}
280 	return (r);
281 }
282 
283 void
idn__labellist_destroy(idn__labellist_t labellist)284 idn__labellist_destroy(idn__labellist_t labellist) {
285 	idn__labellist_t l, l_next;
286 
287 	assert(labellist != NULL);
288 
289 	TRACE(("idn__labellist_destroy()\n"));
290 
291 	for (l = labellist; l != NULL; l = l_next) {
292 		l_next = l->next;
293 		free(l->name);
294 		free(l->undo_name);
295 		free(l->round_trip_name);
296 		free(l);
297 	}
298 
299 	TRACE(("idn__labellist_destroy: the object is destroyed\n"));
300 }
301 
302 idn_result_t
idn__labellist_setname(idn__labellist_t label,const unsigned long * name)303 idn__labellist_setname(idn__labellist_t label, const unsigned long *name) {
304 	idn_result_t r = idn_success;
305 	unsigned long *new_name;
306 
307 	assert(label != NULL && name != NULL);
308 
309 	TRACE(("idn__labellist_setname(name=\"%s\")\n",
310 	       idn__debug_utf32xstring(name)));
311 
312 	new_name = idn__utf32_strdup(name);
313 	if (new_name == NULL) {
314 		r = idn_nomemory;
315 		goto ret;
316 	}
317 
318 	free(label->name);
319 	label->name = new_name;
320 
321 ret:
322 	if (r == idn_success)
323 		TRACE(("idn__labellist_setname(): success\n"));
324 	else {
325 		TRACE(("idn__labellist_setname(): %s\n",
326 		       idn_result_tostring(r)));
327 	}
328 
329 	return (r);
330 }
331 
332 const unsigned long *
idn__labellist_getname(idn__labellist_t label)333 idn__labellist_getname(idn__labellist_t label) {
334 	assert(label != NULL);
335 
336 	TRACE(("idn__labellist_getname(): success (label=\"%s\")\n",
337 	       idn__debug_utf32xstring(label->name)));
338 
339 	return (label->name);
340 }
341 
342 idn_result_t
idn__labellist_getnamelist(idn__labellist_t labellist,unsigned long * name,size_t namelen)343 idn__labellist_getnamelist(idn__labellist_t labellist, unsigned long *name,
344 			   size_t namelen) {
345 	static const unsigned long dot_string[] = {'.', '\0'};
346 	idn_result_t r = idn_success;
347 	unsigned long *name_org = name;
348 	idn__labellist_t l;
349 
350 	assert(labellist != NULL && name != NULL);
351 
352 	TRACE(("idn__labellist_getnamelist(namelen=%d)\n", (int)namelen));
353 
354 	if (namelen == 0) {
355 		r = idn_buffer_overflow;
356 		goto ret;
357 	}
358 
359 	*name = '\0';
360 	for (l = labellist; l != NULL; l = l->next) {
361 		r = idn__utf32_strcat(name, namelen, l->name);
362 		if (r != idn_success)
363 			goto ret;
364 		if (l->dot_followed) {
365 			r = idn__utf32_strcat(name, namelen, dot_string);
366 			if (r != idn_success)
367 				goto ret;
368 		}
369 	}
370 
371 ret:
372 	if (r == idn_success) {
373 		TRACE(("idn__labellist_getnamelist(): success (name=\"%s\")\n",
374 		       idn__debug_utf32xstring(name_org)));
375 	} else {
376 		TRACE(("idn__labellist_getnamelist(): %s\n",
377 		       idn_result_tostring(r)));
378 	}
379 
380 	return (r);
381 }
382 
383 idn_result_t
idn__labellist_setundoname(idn__labellist_t label)384 idn__labellist_setundoname(idn__labellist_t label) {
385 	idn_result_t r = idn_success;
386 	unsigned long *undo_name;
387 
388 	assert(label != NULL);
389 
390 	TRACE(("idn__labellist_setundoname(label=\"%s\")\n",
391 	       idn__debug_utf32xstring(label->name)));
392 
393 	undo_name = idn__utf32_strdup(label->name);
394 	if (undo_name == NULL) {
395 		r = idn_nomemory;
396 		goto ret;
397 	}
398 
399 	free(label->undo_name);
400 	label->undo_name = undo_name;
401 
402 ret:
403 	if (r == idn_success) {
404 		TRACE(("idn__labellist_setundoname(): success "
405 		       "(label=\"%s\")\n",
406 		       idn__debug_utf32xstring(label->undo_name)));
407 	} else {
408 		TRACE(("idn__labellist_setundoname(): %s\n",
409 		       idn_result_tostring(r)));
410 	}
411 
412 	return (r);
413 }
414 
415 idn_result_t
idn__labellist_undo(idn__labellist_t label)416 idn__labellist_undo(idn__labellist_t label) {
417 	idn_result_t r = idn_success;
418 	unsigned long *new_name;
419 
420 	assert(label != NULL);
421 
422 	TRACE(("idn__labellist_undo(label=\"%s\")\n",
423 	       idn__debug_utf32xstring(label->name)));
424 
425 	label->undo_count++;
426 	if (label->undo_name != NULL) {
427 		new_name = idn__utf32_strdup(label->undo_name);
428 		if (new_name == NULL) {
429 			r = idn_nomemory;
430 			goto ret;
431 		}
432 		free(label->name);
433 		label->name = new_name;
434 	}
435 
436 ret:
437 	if (r == idn_success) {
438 		TRACE(("idn__labellist_undo(): success (label=\"%s\")\n",
439 		       idn__debug_utf32xstring(label->name)));
440 	} else {
441 		TRACE(("idn__labellist_undo(): %s\n",
442 		       idn_result_tostring(r)));
443 	}
444 
445 	return (r);
446 }
447 
448 int
idn__labellist_getundocount(idn__labellist_t label)449 idn__labellist_getundocount(idn__labellist_t label) {
450 	return (label->undo_count);
451 }
452 
453 idn_result_t
idn__labellist_setroundtripname(idn__labellist_t label)454 idn__labellist_setroundtripname(idn__labellist_t label) {
455 	idn_result_t r = idn_success;
456 	unsigned long *round_trip_name;
457 
458 	assert(label != NULL);
459 
460 	TRACE(("idn__labellist_setroundtripname(label=\"%s\")\n",
461 	       idn__debug_utf32xstring(label->name)));
462 
463 	round_trip_name = idn__utf32_strdup(label->name);
464 	if (round_trip_name == NULL) {
465 		r = idn_nomemory;
466 		goto ret;
467 	}
468 
469 	free(label->round_trip_name);
470 	label->round_trip_name = round_trip_name;
471 
472 ret:
473 	if (r == idn_success) {
474 		TRACE(("idn__labellist_setroundtripname(): success "
475 		       "(label=\"%s\")\n",
476 		       idn__debug_utf32xstring(label->name)));
477 	} else {
478 		TRACE(("idn__labellist_setroundtripname(): %s\n",
479 		       idn_result_tostring(r)));
480 	}
481 
482 	return (r);
483 }
484 
485 const unsigned long *
idn__labellist_getroundtripname(idn__labellist_t label)486 idn__labellist_getroundtripname(idn__labellist_t label) {
487 	unsigned long *round_trip_name;
488 
489 	assert(label != NULL);
490 
491 	if (label->round_trip_name != NULL)
492 		round_trip_name = label->round_trip_name;
493 	else
494 		round_trip_name = label->name;
495 
496 	TRACE(("idn__labellist_getroundtripname(): success (label=\"%s\")\n",
497 	       idn__debug_utf32xstring(round_trip_name)));
498 
499 	return (round_trip_name);
500 }
501 
502 idn__labellist_t
idn__labellist_next(idn__labellist_t label)503 idn__labellist_next(idn__labellist_t label) {
504 	idn__labellist_t l;
505 
506 	TRACE(("idn__labellist_next(label=\"%s\")\n",
507 	       idn__debug_utf32xstring(label->name)));
508 
509 	l = label->next;
510 
511 	TRACE(("idn__labellist_next(): success (label=\"%s\")\n",
512 	       (l != NULL) ? idn__debug_utf32xstring(l->name) : "<null>"));
513 
514 	return (l);
515 }
516