Subversion Repositories SvarDOS

Rev

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

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