Blame


1 d947271f 2019-02-08 stsp /* $OpenBSD: rcsutil.c,v 1.46 2017/08/29 16:47:33 otto Exp $ */
2 d947271f 2019-02-08 stsp /*
3 d947271f 2019-02-08 stsp * Copyright (c) 2005, 2006 Joris Vink <joris@openbsd.org>
4 d947271f 2019-02-08 stsp * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
5 d947271f 2019-02-08 stsp * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
6 d947271f 2019-02-08 stsp * Copyright (c) 2006 Ray Lai <ray@openbsd.org>
7 d947271f 2019-02-08 stsp * All rights reserved.
8 d947271f 2019-02-08 stsp *
9 d947271f 2019-02-08 stsp * Redistribution and use in source and binary forms, with or without
10 d947271f 2019-02-08 stsp * modification, are permitted provided that the following conditions
11 d947271f 2019-02-08 stsp * are met:
12 d947271f 2019-02-08 stsp *
13 d947271f 2019-02-08 stsp * 1. Redistributions of source code must retain the above copyright
14 d947271f 2019-02-08 stsp * notice, this list of conditions and the following disclaimer.
15 d947271f 2019-02-08 stsp * 2. The name of the author may not be used to endorse or promote products
16 d947271f 2019-02-08 stsp * derived from this software without specific prior written permission.
17 d947271f 2019-02-08 stsp *
18 d947271f 2019-02-08 stsp * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 d947271f 2019-02-08 stsp * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 d947271f 2019-02-08 stsp * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 d947271f 2019-02-08 stsp * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 d947271f 2019-02-08 stsp * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 d947271f 2019-02-08 stsp * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 d947271f 2019-02-08 stsp * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 d947271f 2019-02-08 stsp * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 d947271f 2019-02-08 stsp * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 d947271f 2019-02-08 stsp * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 d947271f 2019-02-08 stsp */
29 d947271f 2019-02-08 stsp
30 8b925c6c 2022-07-16 thomas #include <sys/queue.h>
31 d947271f 2019-02-08 stsp
32 d947271f 2019-02-08 stsp #include <ctype.h>
33 d947271f 2019-02-08 stsp #include <stdio.h>
34 d947271f 2019-02-08 stsp #include <stdlib.h>
35 d947271f 2019-02-08 stsp #include <string.h>
36 d947271f 2019-02-08 stsp #include <unistd.h>
37 d947271f 2019-02-08 stsp
38 dd038bc6 2021-09-21 thomas.ad #include "got_compat.h"
39 dd038bc6 2021-09-21 thomas.ad
40 537a2366 2019-02-08 stsp #include "buf.h"
41 537a2366 2019-02-08 stsp #include "rcsutil.h"
42 d947271f 2019-02-08 stsp
43 d947271f 2019-02-08 stsp /*
44 d947271f 2019-02-08 stsp * Split the contents of a file into a list of lines.
45 d947271f 2019-02-08 stsp */
46 d947271f 2019-02-08 stsp struct rcs_lines *
47 d947271f 2019-02-08 stsp rcs_splitlines(u_char *data, size_t len)
48 d947271f 2019-02-08 stsp {
49 d947271f 2019-02-08 stsp u_char *c, *p;
50 d947271f 2019-02-08 stsp struct rcs_lines *lines;
51 d947271f 2019-02-08 stsp struct rcs_line *lp;
52 d947271f 2019-02-08 stsp size_t i, tlen;
53 d947271f 2019-02-08 stsp
54 537a2366 2019-02-08 stsp lines = calloc(1, sizeof(*lines));
55 537a2366 2019-02-08 stsp if (lines == NULL)
56 537a2366 2019-02-08 stsp return NULL;
57 d947271f 2019-02-08 stsp TAILQ_INIT(&(lines->l_lines));
58 d947271f 2019-02-08 stsp
59 537a2366 2019-02-08 stsp lp = calloc(1, sizeof(*lp));
60 537a2366 2019-02-08 stsp if (lp == NULL) {
61 537a2366 2019-02-08 stsp free(lines);
62 537a2366 2019-02-08 stsp return NULL;
63 537a2366 2019-02-08 stsp }
64 d947271f 2019-02-08 stsp TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list);
65 d947271f 2019-02-08 stsp
66 d947271f 2019-02-08 stsp p = c = data;
67 d947271f 2019-02-08 stsp for (i = 0; i < len; i++) {
68 d947271f 2019-02-08 stsp if (*p == '\n' || (i == len - 1)) {
69 d947271f 2019-02-08 stsp tlen = p - c + 1;
70 537a2366 2019-02-08 stsp lp = malloc(sizeof(*lp));
71 537a2366 2019-02-08 stsp if (lp == NULL) {
72 537a2366 2019-02-08 stsp rcs_freelines(lines);
73 537a2366 2019-02-08 stsp return NULL;
74 537a2366 2019-02-08 stsp }
75 d947271f 2019-02-08 stsp lp->l_line = c;
76 d947271f 2019-02-08 stsp lp->l_len = tlen;
77 d947271f 2019-02-08 stsp lp->l_lineno = ++(lines->l_nblines);
78 d947271f 2019-02-08 stsp TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list);
79 d947271f 2019-02-08 stsp c = p + 1;
80 d947271f 2019-02-08 stsp }
81 d947271f 2019-02-08 stsp p++;
82 d947271f 2019-02-08 stsp }
83 d947271f 2019-02-08 stsp
84 d947271f 2019-02-08 stsp return (lines);
85 d947271f 2019-02-08 stsp }
86 d947271f 2019-02-08 stsp
87 d947271f 2019-02-08 stsp void
88 d947271f 2019-02-08 stsp rcs_freelines(struct rcs_lines *lines)
89 d947271f 2019-02-08 stsp {
90 d947271f 2019-02-08 stsp struct rcs_line *lp;
91 d947271f 2019-02-08 stsp
92 d947271f 2019-02-08 stsp while ((lp = TAILQ_FIRST(&(lines->l_lines))) != NULL) {
93 d947271f 2019-02-08 stsp TAILQ_REMOVE(&(lines->l_lines), lp, l_list);
94 d947271f 2019-02-08 stsp free(lp);
95 d947271f 2019-02-08 stsp }
96 d947271f 2019-02-08 stsp
97 d947271f 2019-02-08 stsp free(lines);
98 d947271f 2019-02-08 stsp }
99 d947271f 2019-02-08 stsp
100 d947271f 2019-02-08 stsp BUF *
101 d947271f 2019-02-08 stsp rcs_patchfile(u_char *data, size_t dlen, u_char *patch, size_t plen,
102 d947271f 2019-02-08 stsp int (*p)(struct rcs_lines *, struct rcs_lines *))
103 d947271f 2019-02-08 stsp {
104 575e8218 2019-10-07 stsp const struct got_error *err = NULL;
105 d947271f 2019-02-08 stsp struct rcs_lines *dlines, *plines;
106 d947271f 2019-02-08 stsp struct rcs_line *lp;
107 d947271f 2019-02-08 stsp BUF *res;
108 537a2366 2019-02-08 stsp size_t newlen;
109 d947271f 2019-02-08 stsp
110 d947271f 2019-02-08 stsp dlines = rcs_splitlines(data, dlen);
111 d947271f 2019-02-08 stsp plines = rcs_splitlines(patch, plen);
112 d947271f 2019-02-08 stsp
113 d947271f 2019-02-08 stsp if (p(dlines, plines) < 0) {
114 d947271f 2019-02-08 stsp rcs_freelines(dlines);
115 d947271f 2019-02-08 stsp rcs_freelines(plines);
116 d947271f 2019-02-08 stsp return (NULL);
117 d947271f 2019-02-08 stsp }
118 d947271f 2019-02-08 stsp
119 575e8218 2019-10-07 stsp err = buf_alloc(&res, 1024);
120 575e8218 2019-10-07 stsp if (err)
121 575e8218 2019-10-07 stsp return NULL;
122 d947271f 2019-02-08 stsp TAILQ_FOREACH(lp, &dlines->l_lines, l_list) {
123 d947271f 2019-02-08 stsp if (lp->l_line == NULL)
124 d947271f 2019-02-08 stsp continue;
125 537a2366 2019-02-08 stsp buf_append(&newlen, res, lp->l_line, lp->l_len);
126 d947271f 2019-02-08 stsp }
127 d947271f 2019-02-08 stsp
128 d947271f 2019-02-08 stsp rcs_freelines(dlines);
129 d947271f 2019-02-08 stsp rcs_freelines(plines);
130 d947271f 2019-02-08 stsp return (res);
131 d947271f 2019-02-08 stsp }