Subversion Repositories SvarDOS

Rev

Rev 240 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 240 Rev 253
1
/*
1
/*
2
 * This file is part of the pkginst (SvarDOS) project.
2
 * This file is part of the pkginst (SvarDOS) project.
3
 * Copyright (C) Mateusz Viste 2012-2021. All rights reserved.
3
 * Copyright (C) Mateusz Viste 2012-2021. All rights reserved.
4
 */
4
 */
5
 
5
 
6
#include <ctype.h>    /* toupper() */
6
#include <ctype.h>    /* toupper() */
7
#include <stdio.h>
7
#include <stdio.h>
8
#include <string.h>    /* strlen() */
8
#include <string.h>    /* strlen() */
9
#include <stdlib.h>    /* free() */
9
#include <stdlib.h>    /* free() */
10
#include <unistd.h>    /* rmdir(), unlink() */
10
#include <unistd.h>    /* rmdir(), unlink() */
11
#include <direct.h>  /* watcom needs this for the rmdir() prototype */
11
#include <direct.h>  /* watcom needs this for the rmdir() prototype */
12
 
12
 
13
#include "fileexst.h"
-
 
14
#include "getdelim.h"
-
 
15
#include "helpers.h"   /* slash2backslash() */
13
#include "helpers.h"   /* slash2backslash() */
16
#include "kprintf.h"
14
#include "kprintf.h"
-
 
15
 
17
#include "pkgrem.h"
16
#include "pkgrem.h"
18
#include "rtrim.h"
-
 
19
#include "version.h"
-
 
20
 
17
 
21
 
18
 
22
struct dirliststruct {
19
struct dirliststruct {
23
  struct dirliststruct *next;
20
  struct dirliststruct *next;
24
  char dirname[2]; /* this must be the last item in the structure */
21
  char dirname[2]; /* this must be the last item in the structure */
25
};
22
};
26
 
23
 
27
 
24
 
28
/* adds a directory to dirlist, if not already present */
25
/* adds a directory to dirlist, if not already present */
29
static struct dirliststruct *rememberdir(struct dirliststruct *dirlist, const char *path) {
26
static struct dirliststruct *rememberdir(struct dirliststruct *dirlist, const char *path) {
30
  struct dirliststruct *res;
27
  struct dirliststruct *res;
31
  /* if already present, do nothing */
28
  /* if already present, do nothing */
32
  for (res = dirlist; res != NULL; res = res->next) {
29
  for (res = dirlist; res != NULL; res = res->next) {
33
    if (strcasecmp(res->dirname, path) == 0) return(dirlist);
30
    if (strcasecmp(res->dirname, path) == 0) return(dirlist);
34
  }
31
  }
35
  /* not in the list yet - add it */
32
  /* not in the list yet - add it */
36
  res = malloc(sizeof(struct dirliststruct) + strlen(path));
33
  res = malloc(sizeof(struct dirliststruct) + strlen(path));
37
  if (res == NULL) {  /* out of memory */
34
  if (res == NULL) {  /* out of memory */
38
    kitten_printf(4, 3, "Out of memory! Could not store directory %s!", path);
35
    kitten_printf(4, 3, "Out of memory! Could not store directory %s!", path);
39
    puts("");
36
    puts("");
40
    return(NULL);
37
    return(NULL);
41
  }
38
  }
42
  strcpy(res->dirname, path);
39
  strcpy(res->dirname, path);
43
  res->next = dirlist;
40
  res->next = dirlist;
44
  return(res);
41
  return(res);
45
}
42
}
46
 
43
 
47
 
44
 
48
/* explode a path into subdirectories, and remember each one inside dirlist */
45
/* explode a path into subdirectories, and remember each one inside dirlist */
49
static struct dirliststruct *rememberpath(struct dirliststruct *dirlist, char *path) {
46
static struct dirliststruct *rememberpath(struct dirliststruct *dirlist, char *path) {
50
  int x, gameover = 0;
47
  int x, gameover = 0;
51
  /* iterate on the path, and add each subdirectory */
48
  /* iterate on the path, and add each subdirectory */
52
  for (x = 0;; x++) {
49
  for (x = 0;; x++) {
53
    switch (path[x]) {
50
    switch (path[x]) {
54
      case 0:
51
      case 0:
55
        gameover = 1;
52
        gameover = 1;
56
      case '/':
53
      case '/':
57
      case '\\':
54
      case '\\':
58
        path[x] = 0;
55
        path[x] = 0;
59
        dirlist = rememberdir(dirlist, path);
56
        dirlist = rememberdir(dirlist, path);
60
        path[x] = '\\';
57
        path[x] = '\\';
61
    }
58
    }
62
    if (gameover != 0) break;
59
    if (gameover != 0) break;
63
  }
60
  }
64
  return(dirlist);
61
  return(dirlist);
65
}
62
}
66
 
63
 
67
 
64
 
68
/* removes a package from the system. Returns 0 on success, non-zero otherwise */
65
/* removes a package from the system. Returns 0 on success, non-zero otherwise */
69
int pkgrem(const char *pkgname, const char *dosdir) {
66
int pkgrem(const char *pkgname, const char *dosdir) {
70
  char fpath[256];
67
  char fpath[256];
71
  char shellcmd[256];
68
  char buff[256];
72
  char *lineptr;
-
 
73
  FILE *flist;
69
  FILE *flist;
74
  int getdelimlen;
-
 
75
  int lastdirsep;
70
  int lastdirsep;
76
  int x;
-
 
77
  size_t getdelimcount = 0;
-
 
78
  struct dirliststruct *dirlist = NULL; /* used to remember directories to remove */
71
  struct dirliststruct *dirlist = NULL; /* used to remember directories to remove */
79
  char pkglistfile[256];
-
 
80
 
72
 
81
  /* Check if the file %DOSDIR%\packages\pkgname.lst exists (if not, the package is not installed) */
73
  /* open the file %DOSDIR%\packages\pkgname.lst */
82
  sprintf(fpath, "%s\\packages\\%s.lst", dosdir, pkgname);
74
  sprintf(fpath, "%s\\packages\\%s.lst", dosdir, pkgname);
83
  if (fileexists(fpath) == 0) { /* file does not exist */
75
  flist = fopen(fpath, "rb");
-
 
76
  if (flist == NULL) {
84
    kitten_printf(4, 0, "Package %s is not installed, so not removed.", pkgname);
77
    kitten_printf(4, 0, "Package %s is not installed, so not removed.", pkgname);
85
    puts("");
78
    puts("");
86
    return(-1);
79
    return(-1);
87
  }
80
  }
88
 
81
 
89
  /* open the file %DOSDIR%\packages\pkgname.lst */
-
 
90
  flist = fopen(fpath, "r");
-
 
91
  if (flist == NULL) {
-
 
92
    kitten_puts(4, 1, "Error opening lst file!");
-
 
93
    return(-2);
-
 
94
  }
-
 
95
 
-
 
96
  sprintf(pkglistfile, "packages\\%s.lst", pkgname);
-
 
97
 
-
 
98
  /* remove all files/folders listed in pkgname.lst but NOT pkgname.lst */
82
  /* remove all files/folders listed in pkgname.lst but NOT pkgname.lst */
99
  for (;;) {
-
 
100
    /* read line from file */
-
 
101
    lineptr = NULL;
-
 
102
    getdelimlen = getdelim(&lineptr, &getdelimcount, '\n', flist);
83
  while (freadtokval(flist, buff, sizeof(buff), NULL, 0) == 0) {
103
    if (getdelimlen < 0) {
-
 
104
      free(lineptr);
-
 
105
      break;
84
    int x;
106
    }
-
 
107
    rtrim(lineptr);  /* right-trim the filename */
-
 
108
    slash2backslash(lineptr); /* change all / to \ */
85
    slash2backslash(buff); /* change all slash to backslash */
109
    if ((lineptr[0] == 0) || (lineptr[0] == '\r') || (lineptr[0] == '\n')) {
-
 
110
      free(lineptr); /* free the memory occupied by the line */
-
 
111
      continue; /* skip empty lines */
86
    if (buff[0] == 0) continue; /* skip empty lines */
112
    }
87
 
113
    /* remember the path part for removal later */
88
    /* remember the path part for removal later */
114
    lastdirsep = -1;
89
    lastdirsep = -1;
115
    for (x = 1; lineptr[x] != 0; x++) {
90
    for (x = 1; buff[x] != 0; x++) {
116
      if ((lineptr[x] == '\\') && (lineptr[x - 1] != ':')) lastdirsep = x;
91
      if ((buff[x] == '\\') && (buff[x - 1] != ':')) lastdirsep = x;
117
    }
92
    }
118
    if (lastdirsep > 0) {
93
    if (lastdirsep > 0) {
119
      lineptr[lastdirsep] = 0;
94
      buff[lastdirsep] = 0;
120
      dirlist = rememberpath(dirlist, lineptr);
95
      dirlist = rememberpath(dirlist, buff);
121
      lineptr[lastdirsep] = '\\';
96
      buff[lastdirsep] = '\\';
122
    }
97
    }
-
 
98
 
123
    /* if it's a directory, skip it */
99
    /* if it's a directory, skip it */
124
    if (lineptr[strlen(lineptr) - 1] == '\\') {
100
    if (buff[strlen(buff) - 1] == '\\') continue;
125
      free(lineptr); /* free the memory occupied by the line */
-
 
126
      continue;
-
 
127
    }
101
 
128
    /* it's a file - remove it */
-
 
129
    if (strcasecmp(pkglistfile, lineptr) != 0) { /* never delete pkgname.lst at this point - it will be deleted later */
102
    /* do not delete pkgname.lst at this point - I am using it (will be deleted later) */
130
      if ((lineptr[0] == '\\') || (lineptr[1] == ':')) { /* this is an absolute path */
-
 
131
        sprintf(shellcmd, "%s", lineptr);
-
 
132
      } else { /* else it's a relative path starting at %dosdir% */
-
 
133
        sprintf(shellcmd, "%s\\%s", dosdir, lineptr);
103
    if (strcasecmp(buff, fpath) == 0) continue;
-
 
104
 
134
      }
105
    /* remove it */
135
      kitten_printf(4, 4, "removing %s", shellcmd);
106
    kitten_printf(4, 4, "removing %s", buff);
136
      puts("");
107
    puts("");
137
      unlink(shellcmd);
108
    unlink(buff);
138
    }
-
 
139
    free(lineptr); /* free the memory occupied by the line */
-
 
140
  }
109
  }
141
 
110
 
142
  /* close the file */
111
  /* close the lst file */
143
  fclose(flist);
112
  fclose(flist);
144
 
113
 
145
  /* iterate through dirlist and remove directories if empty, from longest to shortest */
114
  /* iterate over dirlist and remove directories if empty, from longest to shortest */
146
  while (dirlist != NULL) {
115
  while (dirlist != NULL) {
147
    struct dirliststruct *dirlistpos, *previousdir;
116
    struct dirliststruct *dirlistpos, *previousdir;
148
    /* find the longest path, and put it on top */
117
    /* find the longest path, and put it on top */
149
    previousdir = dirlist;
118
    previousdir = dirlist;
150
    for (dirlistpos = dirlist->next; dirlistpos != NULL; dirlistpos = dirlistpos->next) {
119
    for (dirlistpos = dirlist->next; dirlistpos != NULL; dirlistpos = dirlistpos->next) {
151
      if (strlen(dirlistpos->dirname) > strlen(dirlist->dirname)) {
120
      if (strlen(dirlistpos->dirname) > strlen(dirlist->dirname)) {
152
        previousdir->next = dirlistpos->next;
121
        previousdir->next = dirlistpos->next;
153
        dirlistpos->next = dirlist;
122
        dirlistpos->next = dirlist;
154
        dirlist = dirlistpos;
123
        dirlist = dirlistpos;
155
        dirlistpos = previousdir;
124
        dirlistpos = previousdir;
156
      } else {
125
      } else {
157
        previousdir = dirlistpos;
126
        previousdir = dirlistpos;
158
      }
127
      }
159
    }
128
    }
160
    if ((dirlist->dirname[0] == '\\') || (dirlist->dirname[1] == ':')) { /* this is an absolute path */
-
 
161
      sprintf(shellcmd, "%s", dirlist->dirname);
-
 
162
    } else { /* else it's a relative path starting at %dosdir% */
-
 
163
      sprintf(shellcmd, "%s\\%s", dosdir, dirlist->dirname);
-
 
164
    }
-
 
165
    /* printf("RMDIR %s\n", shellcmd); */
129
    /* printf("RMDIR %s\n", dirlist->dirname); */
166
    rmdir(shellcmd);
130
    rmdir(dirlist->dirname);
167
    /* free the allocated memory for this entry */
131
    /* free the allocated memory for this entry */
168
    dirlistpos = dirlist;
132
    dirlistpos = dirlist;
169
    dirlist = dirlistpos->next;
133
    dirlist = dirlistpos->next;
170
    free(dirlistpos);
134
    free(dirlistpos);
171
  }
135
  }
172
 
136
 
173
  /* remove %DOSDIR%\packages\pkgname.lst */
137
  /* remove the lst file */
174
  unlink(fpath);
138
  unlink(fpath);
175
  kitten_printf(4, 5, "Package %s has been removed.", pkgname);
139
  kitten_printf(4, 5, "Package %s has been removed.", pkgname);
176
  puts("");
140
  puts("");
177
  return(0);
141
  return(0);
178
}
142
}
179
 
143