File: mirrorserver.pike

package info (click to toggle)
roxen 1.2beta2-3
  • links: PTS
  • area: contrib
  • in suites: slink
  • size: 16,920 kB
  • ctags: 8,589
  • sloc: ansic: 89,632; asm: 8,431; sh: 2,915; makefile: 1,784; cpp: 377
file content (146 lines) | stat: -rw-r--r-- 3,080 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <module.h>
inherit "module";

#ifndef MIRRORSERVER_DEBUG
#define MIRRORSERVER_DEBUG
#endif /* MIRRORSERVER_DEBUG */

constant cvs_version = "$Id: mirrorserver.pike,v 1.13 1998/02/04 16:10:46 per Exp $";

class MirrorServer {
  import Stdio;
  string base;
  object fid;

  int open(){ return 1; }


  static class MyFile {
    object q;

    string read(int len)
    {
      return q->read(len);
    }
    
    void create(string fn)
    {
      q = open(fn,"r");
    }
  };


  static class MyStringFile {
    string b;

    string read(int len)
    {
      string q = b[..len-1];
      b = b[len..];
      return q;
    }
    
    void create(string fn)
    {
      b=fn;
    }
  };

  
  object open_file(string url)
  {
    url = replace(base+url,"//","/");
    string foo = roxen->real_file(url, fid);
    if(foo) return MyFile(foo);
    return MyStringFile(fid->conf->try_get_file(url, fid));
  }
  
  string get_file(string url)
  {
    url = replace(base+url,"//","/");
    string foo = roxen->real_file(url, fid);
    if(foo) return read_bytes(foo);
    return fid->conf->try_get_file(url, fid);
  }

  string get_dir(string url)
  {
    url = replace(base+url,"//","/");
    return fid->conf->find_dir(url,fid);
  }

  string stat_file(string url)
  {
    return fid->conf->stat_file(base+url,fid);
  }

  void create(object fi, string ba)
  {
    roxen_perror("Mirror server ok..\n");
    fid = fi;
    base=ba;
  }
}

class FakeID
{
  inherit "protocols/http";

  void create(object c)
  {
    conf = c;
  }
};

array register_module()
{
  return ({0,"Mirror Server",
	     "This is the server end of the Roxen Mirror system.<br>\n"
	     "Add this module to any server you want to mirror <b>on another "
	     "server</b>. You can not mirror to the same Roxen server, since that "
	     "would cause a deadlock (the mirror filesystem does a blocking "
	     "request to the mirror server, which cannot serve it, since the "
	     " mirror filesystem is blocking the Roxen server)\n" });
}

void create()
{
  defvar("port", "any:2000", "Mirror Server port", TYPE_STRING);
  defvar("base", "/", "Base URL", TYPE_STRING);
}

// FIXME: Should probably be destructed on module reload.
object server;
void start(int arg, object conf)
{
  if(conf) {
    mixed err;
    if (err = catch {
      array(string) a = lower_case(query("port"))/":";
      object privs;
      if (((int)a[1]) < 1024)
	privs = Privs("Opening Mirror Server port below 1024 \"" +
		      query("port") + "\"\n");
      server = RoxenRPC.Server(a[0]!="any"?a[0]:0,(int)a[1]);
      privs = 0;
      server->provide("mirror", MirrorServer(FakeID(conf),query("base")));
    }) {
      if (!server) {
	report_error("Failed to initialize Mirror Server on port \"" +
		     query("port") + "\"\n");
      }
#ifdef MIRRORSERVER_DEBUG
      report_error("Error:"+strerror(errno())+"\n"+describe_backtrace(err));
#endif /* MIRRORSERVER_DEBUG */
    }
  }
}

string status()
{
  if (!server) {
    return("<font color=red>Failed to open port.</font>\n");
  } else {
    return("Server is up.\n");
  }
}