~ubuntu-branches/ubuntu/hardy/steam/hardy

« back to all changes in this revision

Viewing changes to spm/spm.in

  • Committer: Bazaar Package Importer
  • Author(s): Alain Schroeder
  • Date: 2006-11-21 16:03:12 UTC
  • mfrom: (2.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061121160312-nf96y6nihzsyd2uv
Tags: 2.2.31-3
Add patch to prevent inconsistent data after shutdown.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!@steamcore@/steam
2
2
 
3
 
/* Copyright (C) 2000-2004  Thomas Bopp, Thorsten Hampel, Ludger Merkens
 
3
/* Copyright (C) 2000-2005  Thomas Bopp, Thorsten Hampel, Ludger Merkens
4
4
 *
5
5
 *  This program is free software; you can redistribute it and/or modify
6
6
 *  it under the terms of the GNU General Public License as published by
16
16
 *  along with this program; if not, write to the Free Software
17
17
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
 * 
19
 
 * $Id: spm.in,v 1.7 2005/03/26 15:14:11 mbaehr Exp $
 
19
 * $Id: spm.in,v 1.13 2006/10/09 21:59:49 exodusd Exp $
20
20
 */
21
21
 
22
 
constant cvs_version="$Id: spm.in,v 1.7 2005/03/26 15:14:11 mbaehr Exp $";
 
22
constant cvs_version="$Id: spm.in,v 1.13 2006/10/09 21:59:49 exodusd Exp $";
23
23
 
24
24
//! steam package manager main script
25
25
//! Installs packages into the main server 
26
26
//! Uploads files by coal and runs pike scripts for preinst and postinst
27
27
inherit "../config";
28
28
 
 
29
#include "../server/include/classes.h"
 
30
#include "../server/include/attributes.h"
 
31
 
29
32
string tmp_dir = "/tmp";
 
33
string pck_name = "";
 
34
 
 
35
string tmp_dir_name;
30
36
 
31
37
static object oInstall;
32
38
 
 
39
static int debug_output = 0;
 
40
static int force = 0;
 
41
 
33
42
object find_object(int id)
34
43
{
35
44
    if ( objectp(oInstall) )
37
46
    return 0;
38
47
}
39
48
 
40
 
void list_packages(mapping options)
 
49
void list_packages( void|string name )
41
50
{
 
51
  if ( stringp(name) && sizeof(name) < 1 ) name = UNDEFINED;
42
52
  object conn = ((program)"connection.pike")();
43
 
 
44
 
  conn->start("www.open-steam.org", 1900, "guest", "guest");
45
 
  conn->list_packages();
 
53
  conn->set_debug( debug_output );
 
54
 
 
55
  conn->start( "steam.open-steam.org", 1900, "guest", "guest" );
 
56
 
 
57
  object _filepath = conn->send_cmd( 0, "get_module", "filepath:tree" );
 
58
  object _packages = conn->send_cmd( _filepath, "path_to_object",
 
59
                                    "/home/admin/packages" );
 
60
  array package_objs = conn->send_cmd( _packages, "get_inventory" );
 
61
  mapping packages = ([ ]);
 
62
  foreach ( package_objs, object pck ) {
 
63
    string desc = conn->send_cmd( pck, "query_attribute", OBJ_DESC );
 
64
    if ( !stringp(desc) ) desc = "";
 
65
    packages[pck->get_identifier()] = desc;
 
66
  }
 
67
 
 
68
  werror("List of packages " + (stringp(name) ? "containing '"+name+"' " : "") + "on sTeam server:\n");
 
69
  foreach( sort(indices(packages)), string package ) {
 
70
    if ( stringp(name) && (search(package, name) < 0) ) continue;
 
71
    werror(" " + package + " : \t" + (string)packages[package] + "\n");
 
72
  }
46
73
}
47
74
 
48
75
int get_package(string pck_name, string filename)
49
76
{
50
77
    object conn = ((program)"connection.pike")();
 
78
    conn->set_debug( debug_output );
51
79
    
52
 
    conn->start("www.open-steam.org", 1900, "guest", "guest");
 
80
    conn->start("steam.open-steam.org", 1900, "guest", "guest");
53
81
    string content = conn->get_package(pck_name);
54
82
    if ( !stringp(content) )
55
83
    return 0;
97
125
    vars = conf;
98
126
}
99
127
 
100
 
//! Generate a random valid filename for a new file
101
 
//! Returns the string of a valid filename in the given directory and with the
102
 
//! given prefix and suffix. The filename will thus be dir+prefix+random+suffix.
103
 
//! At the time of calling, no file with this name existed.
104
 
string make_tmp_filename ( string dir, string prefix, string suffix ) {
 
128
/** Generate a random valid name for a new directory
 
129
 * Returns the string of a valid directory name in the given directory and
 
130
 * with the given prefix and suffix. The name will thus be
 
131
 * dir+prefix+random+suffix.
 
132
 * At the time of calling, no file with this name existed. The directory
 
133
 * will be created and the path returned.
 
134
 */
 
135
string make_tmp_dirname ( string dir, string prefix, string suffix ) {
 
136
  if ( stringp(tmp_dir_name) && sizeof(tmp_dir_name)>0 )
 
137
    return tmp_dir_name;
105
138
  string full_prefix = dir;
106
139
  if ( ! has_suffix( full_prefix, "/" ) ) full_prefix += "/";
107
140
  full_prefix += prefix;
108
 
  string random_fname = "";
 
141
  string random_name = "";
109
142
  Stdio.File tmp_file;
110
143
  mixed err = 0;
111
144
  do {
112
 
    random_fname = full_prefix + replace(MIME.encode_base64(random_string(20),1) + suffix,"/","X");
113
 
  } while ( Stdio.exist(random_fname) );
114
 
  return random_fname;
 
145
    random_name = full_prefix + replace(MIME.encode_base64(random_string(20),1) + suffix,"/","X");
 
146
  } while ( Stdio.exist(random_name) );
 
147
  if ( !Stdio.mkdirhier( random_name ) ) {
 
148
    werror( "Could not create tmp directory: %s\n", random_name );
 
149
    exit( 1 );
 
150
  }
 
151
  tmp_dir_name = random_name;
 
152
  return tmp_dir_name;
 
153
}
 
154
 
 
155
 
 
156
static void cleanup ()
 
157
{
 
158
  // delete the temporary dir:
 
159
  if ( stringp(tmp_dir_name) && sizeof(tmp_dir_name)>0 ) {
 
160
    if ( Stdio.exist(tmp_dir_name) ) {
 
161
      write( "Deleting temporary directory ...\n", tmp_dir_name );
 
162
      if ( !Stdio.recursive_rm( tmp_dir_name ) )
 
163
        werror( "Could not delete temporary directory: %s\n", tmp_dir_name );
 
164
    }
 
165
  }
 
166
  //if ( search(pck_name,tmp_dir) == 0 )
 
167
  //  Filesystem.System()->rm( pck_name );
 
168
}
 
169
 
 
170
int check_spm(string pname, object spmModule, object connection, void|int force)
 
171
{
 
172
    object tfs = Filesystem.Tar(pname);
 
173
    if ( !objectp(tfs) ) {
 
174
      werror(pname + " not a valid SPM !\n");
 
175
      return 0;
 
176
    }
 
177
    mixed xml = tfs->open("package.xml", "r");
 
178
    string packageXML = xml->read();
 
179
    xml->close();
 
180
    mapping config =spmModule->spm_check_configuration(packageXML);
 
181
    mapping pmod = connection->send_cmd(0, "get_module", config->name);
 
182
    if ( !objectp(pmod) )
 
183
      pmod = connection->send_cmd(0, "get_module", "package:"+config->name);
 
184
    if ( objectp(pmod) ) {
 
185
      if ( spmModule->spm_version_value(config->version) <= spmModule->spm_version_value(pmod->get_version()) ) {
 
186
        if ( force ) {
 
187
          write("Found installed module with version %O, forcing installation anyway.\n", pmod->get_version());
 
188
        }
 
189
        else {
 
190
          werror("Found installed module with version %O, skipping installation !\n", pmod->get_version());
 
191
          return 0;
 
192
        }
 
193
      }
 
194
      else {
 
195
        werror("Found installed module - updating to %O (previous version %O)\n",
 
196
               config->version, pmod->get_version());
 
197
      }
 
198
    }
 
199
    return 1;
115
200
}
116
201
 
117
202
 
125
210
int main(int argc, array(string) argv)
126
211
{
127
212
  string server_path = "@steamcore@";
128
 
  string config_path = "@configs@";
 
213
  string config_path = "@configdir@";
129
214
 
130
215
  if ( config_path == "" )
131
216
    config_path = server_path + "/config";
134
219
      write("SPM: sTeam package manager.\n"+
135
220
        "This utility connects to a running local sTeam server and\n"+
136
221
        "installs new packages. Usage is spm <options>:\n"+
137
 
        " -i --install <package-name>: Installs a new package.\n"+
 
222
        " -i --install <package-name>: Installs ar updates a package.\n"+
138
223
        "    The package is either retrieved from the main sTeam server\n"+
139
224
        "    or located on the local disk (package-name can be a path name).\n"+
140
 
        " -l --list: Lists all packages available for installation on the\n"+
141
 
        "    main sTeam server (www.open-steam.org).\n"+
142
 
        " -d --dest: Install the package to the destination directory.\n"+
143
 
        " -c --configure: Just configure a package (if already installed).\n");
 
225
        " -o --old-install <package-name>: Installs or updates a package\n"+
 
226
        "    using the old installation mechanism. This is deprecated and\n"+
 
227
        "    you should only use this method when instructed to.\n"+
 
228
        " -f --force : Forces installation of a package, even if the\n"+
 
229
        "              package is already installed with that version.\n"+
 
230
        " -l --list [name] : Lists all packages available for installation\n"+
 
231
        "    on the main sTeam server (www.open-steam.org). If an argument\n"+
 
232
        "    is given, only packages which contain that text are listed.\n"+
 
233
        " -d --dest <directory> : Install the package to the destination"+
 
234
        "    directory.\n"+
 
235
        " -s --server <hostname> : Install on a given server.\n"+
 
236
        " -p --port <port> : use another port for installation\n"+
 
237
        "    (default is 1900).\n"+
 
238
        " -c --configure <package-name> : Just configure a package\n"+
 
239
        "    (if already installed).\n");
144
240
      return 0;
145
241
  }
146
242
 
147
 
  mapping values = ([ "i":"install", 
148
 
                      "l":"list",
149
 
                      "d":"dest",
150
 
                      "c":"configure",
151
 
                      ]);
152
 
                        
153
 
  mapping options = handle_options(argv[1..], values);
 
243
  atexit( cleanup );
 
244
 
 
245
  // get all command line options:
 
246
  array tmp_options = Getopt.find_all_options( argv, ({
 
247
    ({ "install", Getopt.HAS_ARG, ({ "-i", "--install" }) }),
 
248
    ({ "old-install", Getopt.HAS_ARG, ({ "-o", "--old-install" }) }),
 
249
    ({ "list", Getopt.MAY_HAVE_ARG, ({ "-l", "--list" }), ({ }), "" }),
 
250
    ({ "dest", Getopt.HAS_ARG, ({ "-d", "--dest" }) }),
 
251
    ({ "configure", Getopt.HAS_ARG, ({ "-c", "--configure" }) }),
 
252
    ({ "server", Getopt.HAS_ARG, ({ "-s", "--server" }) }),
 
253
    ({ "port", Getopt.HAS_ARG, ({ "-p", "--port" }) }),
 
254
    ({ "debug", Getopt.NO_ARG, ({ "--debug" }) }),
 
255
    ({ "force", Getopt.NO_ARG, ({ "-f", "--force" }) }),
 
256
  }) );
 
257
  // make a mapping out of the options:
 
258
  mapping options = ([ ]);
 
259
  foreach ( tmp_options, array option ) options[ option[0] ] = option[1];
 
260
  if ( options["debug"] ) debug_output = 1;
 
261
  if ( options["force"] ) force = 1;
154
262
 
155
263
  master()->add_include_path(server_path+"/server/include");
156
264
  master()->add_program_path(server_path+"/server/");
158
266
  master()->add_module_path(server_path+"/server/libraries");
159
267
  master()->add_program_path(server_path+"/server/net/coal");
160
268
  add_constant("find_object", find_object);
161
 
  read_configs(config_path+"/steam.cnf");
 
269
  read_configs(config_path+"/steam.cfg");
162
270
 
163
271
  if ( options["list"] ) {
164
 
      list_packages(options);
 
272
      list_packages( options["list"] );
165
273
      return 0;
166
274
  }
167
275
  
168
 
  werror("OPTIONS\n"+sprintf("%O\n", options));
169
 
  if ( sizeof(options->options) < 1 ) {
170
 
      werror("Missing filename or URL for installation...\n");
 
276
  pck_name = options["install"];
 
277
  if ( !stringp(pck_name) ) pck_name = options["old-install"];
 
278
  if ( !stringp(pck_name) ) pck_name = options["configure"];
 
279
 
 
280
  if ( !stringp(pck_name) ) {
 
281
      werror("Missing filename or URL for installation / configuration...\n");
171
282
      return 1;
172
283
  }
173
 
 
174
 
 
175
 
  string url, pck_name;
176
 
  pck_name = options->options[0];
 
284
  string spm_filename = basename( pck_name );
 
285
  sscanf( spm_filename, "%s.gz", spm_filename );
 
286
 
 
287
  string url;
177
288
  mkdir(dirname(tmp_dir));
178
289
 
179
290
  if ( sscanf(pck_name, "http://%s", url) > 0 ) {
182
293
      mapping headers = ([ ]);
183
294
      string user, pass;
184
295
      if ( sscanf(url, "%s:%s@%s", user, pass, url) == 3 ) {
185
 
      werror("User: "+ user + "\n");
 
296
      write("User: "+ user + "\n");
186
297
      headers = ([ "authorization": "Basic " + 
187
298
        MIME.encode_base64(user+":"+pass), ]);
188
299
      }
189
 
      werror("Connecting to http://" + url+"\n");
 
300
      write("Connecting to http://" + url+"\n");
190
301
      object query = Protocols.HTTP.get_url("http://"+url, ([ ]), headers);
191
302
      mapping d = query->cast("mapping");
192
 
      werror("RESULT=\n"+sprintf("%O\n",indices(d)));
 
303
      //werror("RESULT=\n"+sprintf("%O\n",indices(d)));
193
304
      string data = d->data;
194
305
      string fname;
195
306
      sscanf(url, "%*s/%s", fname);
196
 
      werror("Transfered " + strlen(data) + " bytes...\n");
197
 
      pck_name = make_tmp_filename(tmp_dir,"spm_",basename(fname));
 
307
      write("Transfered " + strlen(data) + " bytes...\n");
 
308
      tmp_dir_name = make_tmp_dirname(tmp_dir,"spm_","");
 
309
      pck_name = tmp_dir_name + "/" + fname;
198
310
      object f = Stdio.File(pck_name, "wct",0600);
199
311
      f->write(data);
200
312
      f->close();
201
313
      
202
 
      werror("Package received...\n");
 
314
      write("Package received...\n");
203
315
  }
204
316
 
205
317
  if ( !Stdio.exist(pck_name) ) {
206
 
      werror("Getting file from package server...\n");
207
 
      string tmp_filename = make_tmp_filename(tmp_dir,"spm_",basename(pck_name));
 
318
      write("Getting file from package server...\n");
 
319
      tmp_dir_name = make_tmp_dirname(tmp_dir,"spm_","");
 
320
      string tmp_filename = tmp_dir_name + "/" + pck_name;
208
321
      if ( !get_package(pck_name, tmp_filename) ) {
209
322
        werror("Package not found on server ... Try -l to list packages.\n");
210
323
        return 1;
213
326
  }
214
327
  master()->add_program_path("../spm");
215
328
 
216
 
        if ( sscanf(pck_name, "%s.gz", pck_name) >= 0 ) {
217
 
                werror("Unzipping...\n");
218
 
                string destname = pck_name;
219
 
                if ( search(destname,tmp_dir) != 0 )
220
 
                        destname = make_tmp_filename(tmp_dir,"spm_",basename(destname));
221
 
                object f = Stdio.File(destname, "wct");
222
 
                int ret = Process.create_process( 
223
 
                        ({ "gunzip", "-c", "-f", pck_name+".gz" }), ([ "stdout" : f ]))->wait();
224
 
                f->close();
225
 
                if ( search(pck_name,tmp_dir) == 0 )
226
 
                        Filesystem.System()->rm( pck_name+".gz" );
227
 
                pck_name = destname;
228
 
        }
 
329
  if ( sscanf(pck_name, "%s.gz", pck_name) >= 1 ) {
 
330
    write("Unzipping...\n");
 
331
    string destname = pck_name;
 
332
    if ( search(destname,tmp_dir) != 0 ) {
 
333
      tmp_dir_name = make_tmp_dirname(tmp_dir,"spm_","");
 
334
      destname = tmp_dir_name + "/" + destname;
 
335
    }
 
336
    object f = Stdio.File(destname, "wct");
 
337
    int ret = Process.create_process( ({ "gunzip", "-c", "-f",
 
338
        pck_name+".gz" }), ([ "stdout" : f ]))->wait();
 
339
    f->close();
 
340
    if ( search(pck_name,tmp_dir) == 0 )
 
341
      Filesystem.System()->rm( pck_name+".gz" );
 
342
    pck_name = destname;
 
343
  }
229
344
 
230
 
  werror("Opening Tar Filesystem...");
 
345
  write("Opening spm archive ...");
231
346
  object fsystem = Filesystem.Tar(pck_name);
232
 
  werror("ok.\n");
233
 
 
234
 
  object conn = ((program)"connection.pike")();
235
 
  string server = "localhost";
236
 
  int port = (int)vars->port;
237
 
 
238
 
  if ( options->server )
239
 
      server = options->server;
240
 
  if ( options->port )
241
 
      port = (int)options->port;
 
347
  write("ok.\n");
 
348
 
 
349
  // check for package.xml
 
350
  if ( !objectp(fsystem) ) {
 
351
    werror("Not a valid spm package (not a tar archive): %s\n", spm_filename);
 
352
    return 1;
 
353
  }
 
354
  if ( options["install"] && search( fsystem->get_dir(), "/package.xml" )<0 ) {
 
355
    werror("The package %s is deprecated (it doesn't contain a /package.xml"
 
356
      +" file).\nYou need to install it with the -o or --old-install "
 
357
      +"command instead:\n  spm -o %s\n", spm_filename, spm_filename);
 
358
    return 1;
 
359
  }
 
360
  if ( options["old-install"]
 
361
       && search( fsystem->get_dir(), "/package.xml" ) >= 0 ) {
 
362
    werror("The package %s is not deprecated (it contains a /package.xml"
 
363
      +" file).\nYou need to install it with the -i or --install "
 
364
      +"command instead:\n  spm -i %s\n", spm_filename, spm_filename);
 
365
    return 1;
 
366
  }
 
367
 
 
368
 
 
369
  string server = options["server"];
 
370
  int port = (int)(vars["port"]);
 
371
  if ( stringp(server) ) port = 1900;
 
372
  else if ( stringp(vars["ip"]) && sizeof(vars["ip"]) )
 
373
    server = vars["ip"];
 
374
  else
 
375
    server = "localhost";
 
376
  if ( stringp(options["port"]) )
 
377
    sscanf( options["port"], "%d", port );
 
378
 
242
379
  write("Connecting sTeam on "+server+":"+port+"\n");
243
 
 
244
 
  string pw = read_input("Root Password for server", "steam");
 
380
  object conn = ((program)"connection.pike")();
 
381
  conn->set_debug( debug_output );
 
382
  string pw = read_password("Root Password for server", "steam");
245
383
 
246
384
  string pname;
247
385
  if ( sscanf(pck_name, "%s.spm", pname) != 1 ) {
258
396
  conn->set_fsystem(fsystem, vars);
259
397
  conn->start(server, port, "root", pw);
260
398
  if ( options->configure ) {
 
399
        //TODO: this is hardcoded to configure only the web package!?
261
400
        conn->configure_web();
262
 
        werror("CONFIGURATION of package completed !");
 
401
        werror("Configuration of package completed !");
 
402
        return 0;
 
403
  }
 
404
 
 
405
  // connect to the server and register the new package module
 
406
  if ( options["old-install"] ) {
 
407
    conn->upload_package(vars);
 
408
    werror("\nInstallation successfull ("+conn->iInstall + " new Files, "+
 
409
           conn->iUpdate + " updated).\n\n");
 
410
    return 0;
 
411
  } else if ( options["install"] ) {
 
412
    object package_file = Stdio.File( pck_name, "r" );
 
413
    object _filepath = conn->send_cmd( 0, "get_module", "filepath:tree" );
 
414
    if ( !objectp(_filepath) ) {
 
415
      werror( "Unable to find filepath module on server!\n" );
 
416
      return 1;
 
417
    }
 
418
    object _spm = conn->send_cmd( 0, "get_module", "SPM" );
 
419
    if ( !objectp(_spm) ) {
 
420
      werror( "Unable to find spm module on server!\n" );
 
421
      return 1;
 
422
    }
 
423
    object dir = conn->send_cmd( _filepath, "path_to_object", "/packages" );
 
424
    object root_dir = conn->send_cmd( _filepath, "path_to_object", "/" );
 
425
    if ( !objectp(dir) || !objectp(root_dir) ) {
 
426
      werror( "Unable to find package or root directory on server!" );
 
427
      return 1;
 
428
    }
 
429
   if ( !check_spm(pck_name, _spm, conn, force) )
263
430
        return 1;
 
431
    object new_obj = conn->send_cmd( dir, "get_object_byname", spm_filename );
 
432
    if ( !objectp(new_obj) ) {
 
433
      object _docfactory = conn->send_cmd( 0, "get_factory", CLASS_DOCUMENT );
 
434
      if ( !objectp(_docfactory) ) {
 
435
        werror( "Unable to find document factory on server!\n" );
 
436
        return 1;
 
437
      }
 
438
      new_obj = conn->send_cmd( _docfactory, "execute", ([ "name": spm_filename, ]) );
 
439
      if ( !objectp(new_obj) ) {
 
440
        werror( "Could not create temporary package file on server!\n" );
 
441
        return 1;
 
442
      }
 
443
      conn->send_cmd( new_obj, "move", dir );
 
444
    }
 
445
    conn->send_cmd( new_obj, "set_content", package_file->read() );
 
446
    package_file->close();
 
447
    write( "Uploaded package %s ...\n", spm_filename );
 
448
    // install:
 
449
    conn->send_cmd( _spm, "install_spm", ({ new_obj, root_dir }) );
 
450
    write( "Installed package %s ...\n", spm_filename );
 
451
    // delete temporary package on server
 
452
    conn->send_cmd( new_obj, "delete" );
 
453
    write( "Deleted temporary package file on server\n" );
264
454
  }
265
 
  /* 
266
 
   * connect to the server and register the new package module
267
 
   */ 
268
 
  conn->upload_package(vars);
269
 
  werror("\nINSTALLATION Successfull, "+conn->iInstall + " new Files, "+
270
 
         conn->iUpdate + " updated.\n\n");
271
 
 
272
 
        // delete the temporary file:
273
 
        if ( search(pck_name,tmp_dir) == 0 )
274
 
                Filesystem.System()->rm( pck_name );
275
455
}