Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 254 → Rev 255

/pkginst/helpers.c
17,100 → 17,6
#include "helpers.h"
 
 
/* translates a version string into a array of integer values. The array must be 8-position long.
returns 0 if parsing was successful, non-zero otherwise.
Accepted formats follow:
300.12.1
1
12.2.34.2-4.5
1.2c
1.01
2013-12-31 */
static int versiontointarr(char *verstr, int *arr) {
int i, vlen, dotcounter = 1, firstcharaftersep = 0;
char *digits[8];
char verstrcopy[16];
 
/* fill the array with zeroes first */
for (i = 0; i < 8; i++) arr[i] = 0;
 
/* first extensively validate the input */
if (verstr == NULL) return(-1);
vlen = strlen(verstr);
if (vlen == 0) return(-1);
if (vlen > 15) return(-1);
if ((verstr[0] < '0') || (verstr[0] > '9')) return(-1); /* a version string must start with a 0..9 digit */
if ((tolower(verstr[vlen - 1]) >= 'a') && (tolower(verstr[vlen - 1]) <= 'z') && (vlen > 1)) { /* remove any letter from the end, and use it as a (very) minor differenciator */
vlen -= 1;
arr[7] = tolower(verstr[vlen]);
}
if ((verstr[vlen - 1] < '0') || (verstr[vlen - 1] > '9')) return(-1); /* a version string must end with a 0..9 digit */
 
digits[0] = verstrcopy;
for (i = 0; i < vlen; i++) {
verstrcopy[i] = verstr[i];
switch (verstr[i]) {
case '.':
case '-':
if (i == 0) return(-1);
if (verstrcopy[i-1] == 0) return(-1); /* do not allow two separators in a row */
if (dotcounter > 6) return(-1);
digits[dotcounter++] = &verstrcopy[i + 1];
verstrcopy[i] = 0;
firstcharaftersep = 1;
break;
case '0':
/* if this is a zero right after a separator, and trailed with a digit
* (as in '1.01'), then enforce a separator first */
if ((firstcharaftersep != 0) && (verstr[i+1] >= '0') && (verstr[i+1] <= '9')) {
if (dotcounter > 6) return(-1);
digits[dotcounter++] = &verstrcopy[i + 1];
verstrcopy[i] = 0;
}
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
firstcharaftersep = 0;
break;
default: /* do not allow any character different than 0..9 or '.' */
return(-1);
break;
}
}
verstrcopy[i] = 0;
/* now that we know the input is sane, let's process it */
for (i = 0; i < dotcounter; i++) {
int tmpint;
tmpint = atoi(digits[i]);
if ((tmpint < 0) || (tmpint > 32000)) return(-1);
arr[i] = tmpint;
}
return(0);
}
 
 
/* compares version strings v1 and v2. Returns 1 if v2 is newer than v1, 0 otherwise, and -1 if comparison is unable to tell */
int isversionnewer(char *v1, char *v2) {
int x1[8], x2[8], i;
if ((v1 == NULL) || (v2 == NULL)) return(-1); /* if input is invalid (NULL), don't continue */
if (strcasecmp(v1, v2) == 0) return(0); /* if both versions are the same, don't continue */
/* check versions of the decimal format 1.23... */
if ((versiontointarr(v1, x1) != 0) || (versiontointarr(v2, x2) != 0)) return(-1);
for (i = 0; i < 8; i++) {
if (x2[i] > x1[i]) return(1);
if (x2[i] < x1[i]) return(0);
}
return(0);
}
 
 
/* change all / to \ in a string */
void slash2backslash(char *str) {
int x;