Subversion Repositories SvarDOS

Rev

Rev 995 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 995 Rev 1678
1
/*
1
/*
2
 * This file is part of pkg (SvarDOS package manager)
2
 * This file is part of pkg (SvarDOS package manager)
3
 * Copyright (C) 2012-2022 Mateusz Viste
3
 * Copyright (C) 2012-2024 Mateusz Viste
4
 *
4
 *
5
 * It contains a few helper function...
5
 * It contains a few helper function...
6
 */
6
 */
7
 
7
 
8
 
8
 
9
#include <ctype.h>    /* tolower() */
9
#include <ctype.h>    /* tolower() */
10
#include <direct.h>   /* provides the mkdir() prototype */
10
#include <direct.h>   /* provides the mkdir() prototype */
11
#include <string.h>   /* */
11
#include <string.h>   /* */
12
#include <stdio.h>    /* sprintf() */
12
#include <stdio.h>    /* sprintf() */
13
#include <stdlib.h>   /* atoi() */
13
#include <stdlib.h>   /* atoi() */
14
#include <sys/stat.h> /* mkdir() */
14
#include <sys/stat.h> /* mkdir() */
15
 
15
 
16
#include "trim.h"
16
#include "trim.h"
17
#include "helpers.h"
17
#include "helpers.h"
18
 
18
 
19
 
19
 
20
/* change all / to \ in a string */
20
/* change all / to \ in a string */
21
void slash2backslash(char *str) {
21
void slash2backslash(char *str) {
22
  int x;
22
  int x;
23
  for (x = 0; str[x] != 0; x++) {
23
  for (x = 0; str[x] != 0; x++) {
24
    if (str[x] == '/') str[x] = '\\';
24
    if (str[x] == '/') str[x] = '\\';
25
  }
25
  }
26
}
26
}
-
 
27
 
-
 
28
 
-
 
29
/* trim CRC from a filename and returns a pointer to the CRC part.
-
 
30
 * this is used to parse filename lines from LSM files */
-
 
31
char *trimfnamecrc(char *fname) {
-
 
32
  while (*fname) {
-
 
33
    if (*fname == '?') {
-
 
34
      *fname = 0;
-
 
35
      return(fname + 1);
-
 
36
    }
-
 
37
    fname++;
-
 
38
  }
-
 
39
  return(0);
-
 
40
}
27
 
41
 
28
 
42
 
29
void removeDoubleBackslashes(char *str) {
43
void removeDoubleBackslashes(char *str) {
30
  char *curpos;
44
  char *curpos;
31
  int x;
45
  int x;
32
  for (;;) {
46
  for (;;) {
33
    curpos = strstr(str, "\\\\");
47
    curpos = strstr(str, "\\\\");
34
    if (curpos == NULL) return; /* job done */
48
    if (curpos == NULL) return; /* job done */
35
    for (x = 1; curpos[x] != 0; x++) {
49
    for (x = 1; curpos[x] != 0; x++) {
36
      curpos[x - 1] = curpos[x];
50
      curpos[x - 1] = curpos[x];
37
    }
51
    }
38
    curpos[x - 1] = 0;
52
    curpos[x - 1] = 0;
39
  }
53
  }
40
}
54
}
41
 
55
 
42
 
56
 
43
/* Find the first occurrence of find in s, ignore case. */
57
/* Find the first occurrence of find in s, ignore case. */
44
char *fdnpkg_strcasestr(const char *s, const char *find) {
58
char *fdnpkg_strcasestr(const char *s, const char *find) {
45
  char c, sc;
59
  char c, sc;
46
  size_t len;
60
  size_t len;
47
  if ((c = *find++) != 0) {
61
  if ((c = *find++) != 0) {
48
    c = tolower((unsigned char)c);
62
    c = tolower((unsigned char)c);
49
    len = strlen(find);
63
    len = strlen(find);
50
    do {
64
    do {
51
      do {
65
      do {
52
        if ((sc = *s++) == 0) return(NULL);
66
        if ((sc = *s++) == 0) return(NULL);
53
      } while ((char)tolower((unsigned char)sc) != c);
67
      } while ((char)tolower((unsigned char)sc) != c);
54
    } while (strncasecmp(s, find, len) != 0);
68
    } while (strncasecmp(s, find, len) != 0);
55
    s--;
69
    s--;
56
  }
70
  }
57
  return((char *)s);
71
  return((char *)s);
58
}
72
}
59
 
73
 
60
 
74
 
61
/* Creates directories recursively */
75
/* Creates directories recursively */
62
void mkpath(char *dirs) {
76
void mkpath(char *dirs) {
63
  int x;
77
  int x;
64
  char savechar;
78
  char savechar;
65
  for (x = 0; dirs[x] != 0; x++) {
79
  for (x = 0; dirs[x] != 0; x++) {
66
    if (((dirs[x] == '/') || (dirs[x] == '\\')) && (x > 0)) {
80
    if (((dirs[x] == '/') || (dirs[x] == '\\')) && (x > 0)) {
67
      if (dirs[x - 1] != ':') { /* avoid d:\ stuff */
81
      if (dirs[x - 1] != ':') { /* avoid d:\ stuff */
68
        savechar = dirs[x];
82
        savechar = dirs[x];
69
        dirs[x] = 0;
83
        dirs[x] = 0;
70
        /* make the dir */
84
        /* make the dir */
71
        mkdir(dirs);
85
        mkdir(dirs);
72
        dirs[x] = savechar;
86
        dirs[x] = savechar;
73
      }
87
      }
74
    }
88
    }
75
  }
89
  }
76
}
90
}
77
 
91
 
78
 
92
 
79
/* returns a pointer to the start of the filename, out of a path\to\file string, and
93
/* returns a pointer to the start of the filename, out of a path\to\file string, and
80
   fills respath with the local folder where the file should be placed. */
94
   fills respath with the local folder where the file should be placed. */
81
char *computelocalpath(char *longfilename, char *respath, const char *dosdir, const struct customdirs *dirlist) {
95
char *computelocalpath(char *longfilename, char *respath, const char *dosdir, const struct customdirs *dirlist) {
82
  int x, lastsep = 0, firstsep = -1;
96
  int x, lastsep = 0, firstsep = -1;
83
  char savedchar;
97
  char savedchar;
84
  char *shortfilename, *pathstart;
98
  char *shortfilename, *pathstart;
85
  pathstart = longfilename;
99
  pathstart = longfilename;
86
  for (x = 0; longfilename[x] != 0; x++) {
100
  for (x = 0; longfilename[x] != 0; x++) {
87
    if ((longfilename[x] == '/') || (longfilename[x] == '\\')) {
101
    if ((longfilename[x] == '/') || (longfilename[x] == '\\')) {
88
      lastsep = x;
102
      lastsep = x;
89
      if (firstsep < 0) firstsep = x;
103
      if (firstsep < 0) firstsep = x;
90
    }
104
    }
91
  }
105
  }
92
  /* if it's a file without any directory, then it goes to C:\ (COMMAND.COM, KERNEL.SYS...) */
106
  /* if it's a file without any directory, then it goes to C:\ (COMMAND.COM, KERNEL.SYS...) */
93
  if (firstsep < 0) {
107
  if (firstsep < 0) {
94
    sprintf(respath, "C:\\");
108
    sprintf(respath, "C:\\");
95
    return(longfilename);
109
    return(longfilename);
96
  }
110
  }
97
  /* */
111
  /* */
98
  shortfilename = &longfilename[lastsep + 1];
112
  shortfilename = &longfilename[lastsep + 1];
99
  /* look for possible custom path */
113
  /* look for possible custom path */
100
  if (firstsep > 0) {
114
  if (firstsep > 0) {
101
    savedchar = longfilename[firstsep];
115
    savedchar = longfilename[firstsep];
102
    longfilename[firstsep] = 0;
116
    longfilename[firstsep] = 0;
103
    for (; dirlist != NULL; dirlist = dirlist->next) {
117
    for (; dirlist != NULL; dirlist = dirlist->next) {
104
      if (fdnpkg_strcasestr(longfilename, dirlist->name) == longfilename) { /* found! */
118
      if (fdnpkg_strcasestr(longfilename, dirlist->name) == longfilename) { /* found! */
105
        /* sprintf(respath, "%s\\%s", dirlist->location, &longfilename[firstsep + 1]); */
119
        /* sprintf(respath, "%s\\%s", dirlist->location, &longfilename[firstsep + 1]); */
106
        pathstart = &longfilename[firstsep + 1];
120
        pathstart = &longfilename[firstsep + 1];
107
        dosdir = dirlist->location;
121
        dosdir = dirlist->location;
108
        break;
122
        break;
109
      }
123
      }
110
    }
124
    }
111
    longfilename[firstsep] = savedchar; /* restore longfilename as it was */
125
    longfilename[firstsep] = savedchar; /* restore longfilename as it was */
112
  }
126
  }
113
  /* apply the default (DOSDIR) path */
127
  /* apply the default (DOSDIR) path */
114
  savedchar = longfilename[lastsep + 1];
128
  savedchar = longfilename[lastsep + 1];
115
  longfilename[lastsep + 1] = 0;
129
  longfilename[lastsep + 1] = 0;
116
  sprintf(respath, "%s\\%s", dosdir, pathstart);
130
  sprintf(respath, "%s\\%s", dosdir, pathstart);
117
  slash2backslash(respath);
131
  slash2backslash(respath);
118
  removeDoubleBackslashes(respath);
132
  removeDoubleBackslashes(respath);
119
  longfilename[lastsep + 1] = savedchar;
133
  longfilename[lastsep + 1] = savedchar;
120
  return(shortfilename);
134
  return(shortfilename);
121
}
135
}
122
 
136
 
123
 
137
 
124
/* analyzes a filename string and returns the pointer to the file's extension
138
/* analyzes a filename string and returns the pointer to the file's extension
125
 * (which can be empty) */
139
 * (which can be empty) */
126
char *getfext(char *fname) {
140
char *getfext(char *fname) {
127
  char *res = NULL;
141
  char *res = NULL;
128
  for (; *fname != 0; fname++) {
142
  for (; *fname != 0; fname++) {
129
    if (*fname == '.') res = fname + 1;
143
    if (*fname == '.') res = fname + 1;
130
  }
144
  }
131
  /* if no dot found, then point to the string's null terminator */
145
  /* if no dot found, then point to the string's null terminator */
132
  if (res == NULL) return(fname);
146
  if (res == NULL) return(fname);
133
  return(res);
147
  return(res);
134
}
148
}
135
 
149
 
136
 
150
 
137
/* reads a line from a "token = value" file, returns 0 on success
151
/* reads a line from a "token = value" file, returns 0 on success
138
 * val (if not NULL) is updated with a pointer to the "value" part
152
 * val (if not NULL) is updated with a pointer to the "value" part
139
 * delim is the delimiter char (typically ':' or '=' but can be anything) */
153
 * delim is the delimiter char (typically ':' or '=' but can be anything) */
140
int freadtokval(FILE *fd, char *line, size_t maxlen, char **val, char delim) {
154
int freadtokval(FILE *fd, char *line, size_t maxlen, char **val, char delim) {
141
  int bytebuff, linelen = 0;
155
  int bytebuff, linelen = 0;
142
  if (val != NULL) *val = NULL;
156
  if (val != NULL) *val = NULL;
143
  for (;;) {
157
  for (;;) {
144
    bytebuff = fgetc(fd);
158
    bytebuff = fgetc(fd);
145
    if (bytebuff == EOF) {
159
    if (bytebuff == EOF) {
146
      if (linelen == 0) return(-1);
160
      if (linelen == 0) return(-1);
147
      break;
161
      break;
148
    }
162
    }
149
    if (bytebuff < 0) return(-1);
163
    if (bytebuff < 0) return(-1);
150
    if ((*val == NULL) && (bytebuff == delim)) {
164
    if ((*val == NULL) && (bytebuff == delim)) {
151
      line[linelen++] = 0;
165
      line[linelen++] = 0;
152
      *val = line + linelen;
166
      *val = line + linelen;
153
      continue;
167
      continue;
154
    }
168
    }
155
    if (bytebuff == '\r') continue; /* ignore CR */
169
    if (bytebuff == '\r') continue; /* ignore CR */
156
    if (bytebuff == '\n') break;
170
    if (bytebuff == '\n') break;
157
    if (linelen < maxlen - 1) line[linelen++] = bytebuff;
171
    if (linelen < maxlen - 1) line[linelen++] = bytebuff;
158
  }
172
  }
159
  /* terminate line and trim token and value (if any) */
173
  /* terminate line and trim token and value (if any) */
160
  line[linelen] = 0;
174
  line[linelen] = 0;
161
  trim(line);
175
  trim(line);
162
  if ((val != NULL) && (*val != NULL)) trim(*val);
176
  if ((val != NULL) && (*val != NULL)) trim(*val);
163
  return(0);
177
  return(0);
164
}
178
}
165
 
179