1 /*
2  * Copyright (C) 2012-2013 Red Hat, Inc.
3  *
4  * Licensed under the GNU Lesser General Public License Version 2.1
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <sys/utsname.h>
26 #include <sys/stat.h>
27 
28 #ifdef __APPLE__
29 typedef int auxv_t;
30 #ifndef AT_HWCAP2
31 #define AT_HWCAP2 26
32 #endif
33 #ifndef AT_HWCAP
34 #define AT_HWCAP 16
35 #endif
getauxval(unsigned long type)36 static unsigned long getauxval(unsigned long type)
37 {
38   unsigned long ret = 0;
39   return ret;
40 }
41 #else
42 #endif
43 
44 // hawkey
45 #include "dnf-types.h"
46 #include "hy-iutil-private.hpp"
47 #include "nevra.hpp"
48 #include "hy-package.h"
49 #include "hy-subject.h"
50 #include "hy-util-private.hpp"
51 
52 #include <memory>
53 
54 /* ARM specific HWCAP defines may be missing on non-ARM devices */
55 #ifndef HWCAP_ARM_VFP
56 #define HWCAP_ARM_VFP	(1<<6)
57 #endif
58 #ifndef HWCAP_ARM_NEON
59 #define HWCAP_ARM_NEON	(1<<12)
60 #endif
61 
62 const char *
hy_chksum_name(int chksum_type)63 hy_chksum_name(int chksum_type)
64 {
65     switch (chksum_type) {
66     case G_CHECKSUM_MD5:
67         return "md5";
68     case G_CHECKSUM_SHA1:
69         return "sha1";
70     case G_CHECKSUM_SHA256:
71         return "sha256";
72     case G_CHECKSUM_SHA384:
73         return "sha384";
74     case G_CHECKSUM_SHA512:
75         return "sha512";
76     default:
77         return NULL;
78     }
79 }
80 
81 int
hy_chksum_type(const char * chksum_name)82 hy_chksum_type(const char *chksum_name)
83 {
84     if (!strcasecmp(chksum_name, "md5"))
85         return G_CHECKSUM_MD5;
86     if (!strcasecmp(chksum_name, "sha1"))
87         return G_CHECKSUM_SHA1;
88     if (!strcasecmp(chksum_name, "sha256"))
89         return G_CHECKSUM_SHA256;
90     if (!strcasecmp(chksum_name, "sha384"))
91         return G_CHECKSUM_SHA384;
92     if (!strcasecmp(chksum_name, "sha512"))
93         return G_CHECKSUM_SHA512;
94     return 0;
95 }
96 
97 char *
hy_chksum_str(const unsigned char * chksum,int type)98 hy_chksum_str(const unsigned char *chksum, int type)
99 {
100     int length = checksum_type2length(type);
101     if (length==-1)
102         return NULL;
103     char *s = static_cast<char *>(g_malloc(2 * length + 1));
104     solv_bin2hex(chksum, length, s);
105 
106     return s;
107 }
108 
109 #define MAX_ARCH_LENGTH 64
110 
111 int
hy_detect_arch(char ** arch)112 hy_detect_arch(char **arch)
113 {
114     struct utsname un;
115 
116     if (uname(&un) < 0)
117         return DNF_ERROR_FAILED;
118 
119     if (!strncmp(un.machine, "armv", 4)) {
120         /* un.machine is armvXE, where X is version number and E is
121          * endianness (b or l); we need to add modifiers such as
122          * h (hardfloat), n (neon). Neon is a requirement of armv8 so
123          * as far as rpm is concerned armv8l is the equivilent of armv7hnl
124          * (or 7hnb) so we don't explicitly add 'n' for 8+ as it's expected. */
125         char endian = un.machine[strlen(un.machine)-1];
126         char *modifier = un.machine + 5;
127         while(isdigit(*modifier)) /* keep armv7, armv8, armv9, armv10, armv100, ... */
128             modifier++;
129 #if !defined(__FreeBSD__)
130         if (getauxval(AT_HWCAP) & HWCAP_ARM_VFP)
131             *modifier++ = 'h';
132         if ((atoi(un.machine+4) == 7) && (getauxval(AT_HWCAP) & HWCAP_ARM_NEON))
133             *modifier++ = 'n';
134 #endif
135         *modifier++ = endian;
136         *modifier = 0;
137     }
138 #ifdef __MIPSEL__
139     if (!strcmp(un.machine, "mips"))
140         strcpy(un.machine, "mipsel");
141     else if (!strcmp(un.machine, "mips64"))
142         strcpy(un.machine, "mips64el");
143 #endif
144     *arch = g_strdup(un.machine);
145     return 0;
146 }
147 
148 #undef MAX_ARCH_LENGTH
149 
150 gboolean
hy_is_glob_pattern(const char * pattern)151 hy_is_glob_pattern(const char *pattern)
152 {
153     return strpbrk(pattern, "*[?") != NULL;
154 }
155 
156 int
hy_split_nevra(const char * nevra,char ** name,int * epoch,char ** version,char ** release,char ** arch)157 hy_split_nevra(const char *nevra, char **name, int *epoch,
158                char **version, char **release, char **arch)
159 {
160     if (strlen(nevra) <= 0)
161         return DNF_ERROR_INTERNAL_ERROR;
162     libdnf::Nevra nevraObj;
163     if (nevraObj.parse(nevra, HY_FORM_NEVRA)) {
164         *arch = g_strdup(nevraObj.getArch().c_str());
165         *name = g_strdup(nevraObj.getName().c_str());
166         *release = g_strdup(nevraObj.getRelease().c_str());
167         *version = g_strdup(nevraObj.getVersion().c_str());
168         *epoch = nevraObj.getEpoch();
169         if (*epoch == -1)
170             *epoch = 0;
171         return 0;
172     }
173     return DNF_ERROR_INTERNAL_ERROR;
174 }
175 
176 GPtrArray *
hy_packagelist_create(void)177 hy_packagelist_create(void)
178 {
179     return (GPtrArray *)g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
180 }
181 
182 int
hy_packagelist_has(GPtrArray * plist,DnfPackage * pkg)183 hy_packagelist_has(GPtrArray *plist, DnfPackage *pkg)
184 {
185     GPtrArray *a = (GPtrArray*)plist;
186     for (guint i = 0; i < a->len; ++i)
187         if (dnf_package_get_identical(pkg, static_cast<DnfPackage *>(a->pdata[i])))
188             return 1;
189     return 0;
190 }
191 
192 int
mtime(const char * filename)193 mtime(const char *filename)
194 {
195     struct stat st;
196     stat(filename, &st);
197     return st.st_mtime;
198 }
199