Subversion Repositories SvarDOS

Rev

Rev 1678 | Rev 1892 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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