Cleanup error_list stuff a bit more.
[oweals/opkg-lede.git] / libopkg / opkg_utils.c
1 /* opkg_utils.c - the opkg package management system
2
3    Steven M. Ayer
4    
5    Copyright (C) 2002 Compaq Computer Corporation
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2, or (at
10    your option) any later version.
11
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 */
17
18 #include "includes.h"
19 #include <errno.h>
20 #include <ctype.h>
21 #include <sys/vfs.h>
22
23 #include "opkg_utils.h"
24 #include "pkg.h"
25 #include "pkg_hash.h"
26
27 void print_pkg_status(pkg_t * pkg, FILE * file);
28
29 long unsigned int get_available_blocks(char * filesystem)
30 {
31     struct statfs sfs;
32
33     if(statfs(filesystem, &sfs)){
34         fprintf(stderr, "bad statfs\n");
35         return 0;
36     }
37     /*    fprintf(stderr, "reported fs type %x\n", sfs.f_type); */
38
39     // Actually ((sfs.f_bavail * sfs.f_bsize) / 1024) 
40     // and here we try to avoid overflow. 
41     if (sfs.f_bsize >= 1024) 
42         return (sfs.f_bavail * (sfs.f_bsize / 1024));
43     else if (sfs.f_bsize > 0)
44         return sfs.f_bavail / (1024 / sfs.f_bsize);
45     fprintf(stderr, "bad statfs f_bsize == 0\n");
46     return 0;
47 }
48
49 char **read_raw_pkgs_from_file(const char *file_name)
50 {
51      FILE *fp; 
52      char **ret;
53     
54      if(!(fp = fopen(file_name, "r"))){
55           fprintf(stderr, "can't get %s open for read\n", file_name);
56           return NULL;
57      }
58
59      ret = read_raw_pkgs_from_stream(fp);
60
61      fclose(fp);
62
63      return ret;
64 }
65
66 char **read_raw_pkgs_from_stream(FILE *fp)
67 {    
68      char **raw = NULL, *buf, *scout;
69      int count = 0;
70      size_t size = 512;
71      
72      buf = calloc (1, size);
73
74      while (fgets(buf, size, fp)) {
75           while (strlen (buf) == (size - 1)
76                  && buf[size-2] != '\n') {
77                size_t o = size - 1;
78                size *= 2;
79                buf = realloc (buf, size);
80                if (fgets (buf + o, size - o, fp) == NULL)
81                     break;
82           }
83           
84           if(!(count % 50))
85                raw = realloc(raw, (count + 50) * sizeof(char *));
86         
87           if((scout = strchr(buf, '\n')))
88                *scout = '\0';
89
90           raw[count++] = strdup(buf);
91      }
92     
93      raw = realloc(raw, (count + 1) * sizeof(char *));
94      raw[count] = NULL;
95
96      free (buf);
97     
98      return raw;
99 }
100
101 /* something to remove whitespace, a hash pooper */
102 char *trim_alloc(char *line)
103 {
104      char *new; 
105      char *dest, *src, *end;
106     
107      new = calloc(1, strlen(line) + 1);
108      if ( new == NULL ){
109         fprintf(stderr,"%s: Unable to allocate memory\n",__FUNCTION__);
110         return NULL;
111      }
112      dest = new, src = line, end = line + (strlen(line) - 1);
113
114      /* remove it from the front */    
115      while(src && 
116            isspace(*src) &&
117            *src)
118           src++;
119      /* and now from the back */
120      while((end > src) &&
121            isspace(*end))
122           end--;
123      end++;
124      *end = '\0';
125      strcpy(new, src);
126      /* this does from the first space
127       *  blasting away any versions stuff in depends
128       while(src && 
129       !isspace(*src) &&
130       *src)
131       *dest++ = *src++;
132       *dest = '\0';
133       */
134     
135      return new;
136 }
137
138 int line_is_blank(const char *line)
139 {
140      const char *s;
141
142      for (s = line; *s; s++) {
143           if (!isspace(*s))
144                return 0;
145      }
146      return 1;
147 }
148
149 static struct errlist *error_list_head, *error_list_tail;
150
151 /*
152  * XXX: this function should not allocate memory as it may be called to
153  *      print an error because we are out of memory.
154  */
155 void push_error_list(char * msg)
156 {
157         struct errlist *e;
158
159         e = calloc(1,  sizeof(struct errlist));
160         if (e == NULL) {
161                 fprintf(stderr, "%s: calloc: %s\n",
162                                 __FUNCTION__, strerror(errno));
163                 return;
164         }
165
166         e->errmsg = strdup(msg);
167         if (e->errmsg == NULL) {
168                 fprintf(stderr, "%s: strdup: %s\n",
169                                 __FUNCTION__, strerror(errno));
170                 free(e);
171                 return;
172         }
173
174         e->next = NULL;
175
176         if (error_list_head) {
177                 error_list_tail->next = e;
178                 error_list_tail = e;
179         } else {
180                 error_list_head = error_list_tail = e;
181         }
182 }
183
184 void free_error_list(void)
185 {
186         struct errlist *err, *err_tmp;
187
188         err = error_list_head;
189         while (err != NULL) {
190                 free(err->errmsg);
191                 err_tmp = err;
192                 err = err->next;
193                 free(err_tmp);
194         }
195 }
196
197 void print_error_list (void)
198 {
199         struct errlist *err = error_list_head;
200
201         if (err) {
202                 printf ("Collected errors:\n");
203                 /* Here we print the errors collected and free the list */
204                 while (err != NULL) {
205                         printf (" * %s", err->errmsg);
206                         err = err->next;
207                 }
208         }
209 }