bug fix 8648 - delete the tarball when uninstalling
[scilab.git] / scilab / modules / atoms / macros / atomsRemove.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2009-2010 - DIGITEO - Pierre MARECHAL <pierre.marechal@scilab.org>
3 //
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
9
10 // End user function
11
12 // Remove a toolbox
13
14 function result = atomsRemove(packages,section,del)
15
16     result = [];
17
18     // Load Atoms Internals lib if it's not already loaded
19     // =========================================================================
20     if ~ exists("atomsinternalslib") then
21         load("SCI/modules/atoms/macros/atoms_internals/lib");
22     end
23
24     // Check write access on allusers zone
25     // =========================================================================
26     ATOMSALLUSERSWRITEACCESS = atomsAUWriteAccess();
27
28     // Save the initial path
29     // =========================================================================
30     ATOMSINITIALPATH = pwd();
31
32     // Get scilab version (needed for later)
33     // =========================================================================
34     sciversion = strcat(string(getversion('scilab')) + ".");
35
36     // Check input parameters
37     // =========================================================================
38
39     rhs = argn(2);
40
41     if rhs < 1 | rhs > 3 then
42         error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"atomsRemove",1,3))
43     end
44
45     if type(packages) <> 10 then
46         error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsRemove",1));
47     end
48
49     if size(packages(1,:),"*") > 2 then
50         error(msprintf(gettext("%s: Wrong size for input argument #%d: mx1 or mx2 string matrix expected.\n"),"atomsInstall",1));
51     end
52
53     packages = stripblanks(packages);
54
55     // If mx1 matrix, add a 2nd column with empty versions
56     // =========================================================================
57     if size(packages(1,:),"*") == 1 then
58         packages = [ packages emptystr(size(packages(:,1),"*"),1) ];
59     end
60
61     // Operating system detection + Architecture detection
62     // =========================================================================
63     [OSNAME,ARCH,LINUX,MACOSX,SOLARIS,BSD] = atomsGetPlatform();
64
65     // Verbose Mode ?
66     // =========================================================================
67     if strcmpi(atomsGetConfig("Verbose"),"True") == 0 then
68         ATOMSVERBOSE = %T;
69     else
70         ATOMSVERBOSE = %F;
71     end
72
73     // Allusers/user management
74     //   - If section is equal to "all" or to True, packages located in both
75     //     "allusers" and "user" sections will removed.
76     //   - If section is equal to "allusers", only packages located in the
77     //     "allusers" section will be removed.
78     //   - If section is equal to "user" or to False, only packages located in
79     //     the "user" will be removed
80     // =========================================================================
81
82     if rhs <= 1 then
83
84         // By default:
85         //  → Remove packages located in both "allusers" and "user" sections if
86         //    we have the write access to SCI directory
87         //  → Remove only package located in the "user" sections otherwise
88
89         if ATOMSALLUSERSWRITEACCESS then
90             section = "all";
91         else
92             section = "user";
93         end
94
95         del = %F;
96
97     elseif rhs==2 then
98
99         // Process the 2nd input argument : section
100         // Allusers can be a boolean or equal to "user" or "allusers"
101
102         if typeof(section) <> "string" & typeof(section) <> "boolean" then
103             error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean or single string expected.\n"),"atomsRemove",2));
104         end
105
106         if size(section, "*") <> 1 then
107             error(msprintf(gettext("%s: Wrong size for input argument #%d: A boolean or single string expected.\n"),"atomsRemove",2));
108         end
109
110         if typeof(section) == "string" then
111             if and(section<>["user","allusers","all"]) then
112                 error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' or ''all'' expected.\n"),"atomsRemove",1));
113             end
114
115             // Check if we have the write access
116             if or(section==["all","allusers"]) & ~ ATOMSALLUSERSWRITEACCESS then
117                 error(msprintf(gettext("%s: You haven''t write access on this directory : %s.\n"),"atomsRemove",2,atomsPath("system","user")));
118             end
119
120             del = %F;
121         else
122             del = section;
123             if ATOMSALLUSERSWRITEACCESS then
124                 section = "all";
125             else
126                 section = "user";
127             end
128         end
129
130     else
131
132         if typeof(section) <> "string" then
133             error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean or single string expected.\n"),"atomsRemove",2));
134         end
135
136         if size(section, "*") <> 1 then
137             error(msprintf(gettext("%s: Wrong size for input argument #%d: A boolean or single string expected.\n"),"atomsRemove",2));
138         end
139
140         // Process the 3rd input argument : delete
141         if typeof(del) <> "boolean" then
142             error(msprintf(gettext("%s: Wrong type for input argument #%d: A boolean expected.\n"),"atomsRemove",3));
143         end
144
145         if size(del, "*") <> 1 then
146             error(msprintf(gettext("%s: Wrong size for input argument #%d: A boolean expected.\n"),"atomsRemove",3));
147         end
148
149         if typeof(section) == "string" then
150             if and(section<>["user","allusers","all"]) then
151                 error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' or ''all'' expected.\n"),"atomsRemove",1));
152             end
153
154             // Check if we have the write access
155             if or(section==["all","allusers"]) & ~ ATOMSALLUSERSWRITEACCESS then
156                 error(msprintf(gettext("%s: You haven''t write access on this directory : %s.\n"),"atomsRemove",2,atomsPath("system","user")));
157             end
158         end
159     end
160
161     // Some checking on packages variable
162     // =========================================================================
163
164     for i=1:size(packages(:,1),"*")
165
166         package_names(i)    = packages(i,1);
167         package_versions(i) = packages(i,2);
168
169         // Check if this package is installed
170         if ~ atomsIsInstalled([package_names(i) package_versions(i)],section) then
171
172             // Print a warning if the package isn't installed
173
174             if isempty(package_versions(i)) then
175                 atomsDisp(msprintf("\t%s isn''t installed",package_names(i)));
176             else
177                 atomsDisp(msprintf("\t%s (%s) isn''t installed",package_names(i),package_versions(i)));
178             end
179
180         elseif (section=="user") & (~ isempty(package_versions(i)) ) then
181
182             // The package is installed, now check if we have the right to
183             // uninstall it
184
185             installed_details = atomsGetInstalledDetails(packages(i,:),section);
186
187             if installed_details(3) == "allusers" then
188                 error(msprintf(gettext("%s: You have not enough rights to remove the package %s (%s).\n"),"atomsRemove",package_names(i),package_versions(i)));
189             end
190
191         elseif (section=="user") & isempty(package_versions(i)) then
192
193             // Check if we have the right to remove at least one of the version
194             // of the package
195             if isempty(atomsGetInstalledVers(package_names(i),section)) then
196                 error(msprintf(gettext("%s: You have not enough rights to remove any version of the package %s.\n"),"atomsRemove",package_names(i)));
197             end
198
199         end
200
201     end
202
203     // Build the list of package to Uninstall
204     // =========================================================================
205     remove_package_list = atomsRemoveList(packages,section);
206     // Loop on remList to print if a package has to be remove
207     // or not
208     // =========================================================================
209     if ATOMSVERBOSE
210         for i=1:size(remove_package_list(:,1),"*")
211             if remove_package_list(i,1) == "-" then
212                 if del==%T then
213                     atomsDisp(msprintf("\t%s (%s) will be removed from the ''%s'' section and its package fully deleted",remove_package_list(i,3),remove_package_list(i,4),remove_package_list(i,5)));
214                 else
215                     atomsDisp(msprintf("\t%s (%s) will be removed from the ''%s'' section",remove_package_list(i,3),remove_package_list(i,4),remove_package_list(i,5)));
216                 end
217             elseif (remove_package_list(i,1) == "~") & (remove_package_list(i,1) == "B") then
218                 atomsDisp(msprintf("\t%s (%s) cannot be removed from the ''%s'' section and will be broken",remove_package_list(i,3),remove_package_list(i,4),remove_package_list(i,5)));
219             end
220         end
221     end
222
223     // Now we have the list of package that have to be uninstalled
224     // =========================================================================
225
226     for i=1:size(remove_package_list(:,1),"*")
227
228         // If the package must be keeped, the job is done
229         if remove_package_list(i,1) <> "-" then
230             continue;
231         end
232
233         this_package_name      = remove_package_list(i,3);
234         this_package_version   = remove_package_list(i,4);
235         this_package_section   = remove_package_list(i,5);
236
237         this_package_details   = atomsToolboxDetails([this_package_name this_package_version]);
238         this_package_insdet    = atomsGetInstalledDetails([this_package_name this_package_version],section);
239         this_package_directory = this_package_insdet(4);
240
241         // Add the package to list of package to remove
242         atomsToremoveRegister(this_package_name,this_package_version,this_package_section);
243
244         // Check if the package is loaded or not
245         if atomsIsLoaded([this_package_name this_package_version]) then
246             mprintf( "\tthe package %s (%s) is currently loaded, It will be removed at next Scilab start\n" , this_package_name , this_package_version );
247             continue;
248         end
249
250         atomsDisp(msprintf(gettext("Removing %s (%s)(%s).\n\n"), this_package_name , this_package_version , this_package_section));
251
252         // Check if this_package_directory start with SCI or SCIHOME
253
254         if  (grep(this_package_directory,pathconvert(SCI)) == []) & ..
255             (grep(this_package_directory,pathconvert(SCIHOME)) == []) &..
256             (grep(this_package_directory,"/^(SCI|SCIHOME)\"+filesep()+"/","r") == []) then
257
258             atomsError("error", ..
259             msprintf( ..
260             gettext("%s: The directory of this package (%s-%s) is located neither in SCI nor in SCIHOME. For security reason, ATOMS refuses to delete this directory.\n"), ..
261             "atomsRemove", ..
262             this_package_name, ..
263             this_package_version));
264         end
265
266         if isdir(this_package_directory) then
267
268             uninstall_status = rmdir(this_package_directory,"s");
269
270             if uninstall_status<>1 then
271                 atomsError("error", ..
272                 msprintf( ..
273                 gettext("%s: The directory of this package (%s-%s) cannot been deleted, please check if you have write access on this directory : %s.\n"), ..
274                 "atomsRemove", ..
275                 this_package_name, ..
276                 this_package_version, ..
277                 strsubst(this_package_directory,"\","\\") ));
278             end
279
280         end
281
282         // Check if the parent directory (directory name == toolbox name ) is empty
283         // If yes, delete it
284         // =====================================================================
285         this_package_root_dir = part(this_package_directory,1:length(pathconvert(this_package_directory,%t,%f)) - length(this_package_version) - 1 );
286
287         if isdir(this_package_root_dir) & listfiles(this_package_root_dir)==[] then
288             stat = rmdir(this_package_root_dir);
289             if stat<>1 then
290                 atomsError("error", ..
291                 msprintf( ..
292                 gettext("%s: The root directory of this package (%s-%s) cannot been deleted, please check if you have write access on this directory : %s.\n"), ..
293                 "atomsRemove", ..
294                 this_package_name, ..
295                 this_package_version, ..
296                 strsubst(this_package_root_dir,"\","\\") ));
297             end
298         end
299
300         // Remove the tarball file if asked
301         if del==%T then
302             atomsDisp(msprintf(gettext("Deleting archives files for %s.\n\n"),this_package_name));
303             atomsDeleteTarball(this_package_name,section,this_package_version);
304         end
305
306         // Remove this toolbox from the list of installed packages
307         // =====================================================================
308         atomsInstallUnregister(this_package_name,this_package_version,this_package_section);
309
310         // Remove this toolbox from the list of autoloaded packages
311         // =====================================================================
312         atomsAutoloadDel([this_package_name this_package_version this_package_section]);
313
314         // Remove it from the DESCRIPTION_installed file
315         // =====================================================================
316
317         DESCRIPTION_file = atomsPath("system",this_package_insdet(3)) + "DESCRIPTION_installed";
318
319         if ~ isempty(fileinfo(DESCRIPTION_file)) then
320             DESCRIPTION = atomsDESCRIPTIONread(DESCRIPTION_file);
321             DESCRIPTION = atomsDESCRIPTIONrm(DESCRIPTION,this_package_name,this_package_version);
322             atomsDESCRIPTIONwrite(DESCRIPTION,DESCRIPTION_file);
323         end
324
325         // Del the package from the list of package to remove
326         // =====================================================================
327         atomsToremoveUnregister(this_package_name,this_package_version,this_package_section);
328
329         // Fill the result matrix
330         // =====================================================================
331         result = [ result ; this_package_insdet ];
332
333         // Sucess message if needed
334         // =====================================================================
335         atomsDisp(msprintf(" success"));
336     end
337
338     // Go to the initial location
339     chdir(ATOMSINITIALPATH);
340
341 endfunction