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
  
/* Auth.pmod 
 */ 
 
/* 
 *    Protocols.X, a Pike interface to the X Window System 
 * 
 *    See COPYRIGHT for copyright information. 
 * 
 *    This program is free software; you can redistribute it and/or modify 
 *    it under the terms of the GNU General Public License as published by 
 *    the Free Software Foundation; either version 2 of the License, or 
 *    (at your option) any later version. 
 * 
 *    This program is distributed in the hope that it will be useful, 
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *    GNU General Public License for more details. 
 * 
 *    You should have received a copy of the GNU General Public License 
 *    along with this program; if not, write to the Free Software 
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */ 
 
#pike __REAL_VERSION__ 
 
class auth_file 
{ 
  mapping(int:mapping(string:mapping)) auth = ([]); 
 
  string make_key(string address, int display) 
  { 
    return sprintf("%d:%s", display, address); 
  } 
 
  void create(string s) 
  { 
    Stdio.Buffer struct = Stdio.Buffer(s); 
 
    while (sizeof(struct)) 
      { 
        mapping m = ([ ]); 
 
        m->family = struct->read_int(2); 
        m->address = struct->read_hstring(2); 
        m->display = (int) struct->read_hstring(2); 
        m->name = struct->read_hstring(2); 
        m->data = struct->read_hstring(2); 
 
        if (!auth[m->family]) 
          auth[m->family] = ([]); 
 
        auth[m->family][make_key(m->address, m->display)] = m; 
      } 
  } 
 
  mapping lookup_local(string name, int display) 
  { 
    return auth[256] && auth[256][make_key(name, display)]; 
  } 
 
  string ip2string(string ip) 
  { 
    return sprintf("%@c", Array.map(ip / ".", 
                                    lambda(string s) 
                                    { return (int) s; })); 
  } 
 
  mapping lookup_ip(string ip, int display) 
  { 
    if(ip == "127.0.0.1") 
      return lookup_local(gethostname(), display); 
    return auth[0] && auth[0][make_key(ip2string(ip), display)]; 
  } 
} 
 
class lock_key 
{ 
  string name; 
  string c_name; 
  string l_name; 
 
  void create(string f) 
  { 
    name = f; 
    c_name = name + "-c"; 
    l_name = name + "-l"; 
  } 
 
  int my_hardlink(string from, string to) 
  { 
#if constant(hardlink) 
    return !catch(hardlink(from, to)); 
#else 
    return 0; // Failed, hubbe 
#endif 
  } 
 
 
  object lock() 
  { 
    object f = Stdio.File(); 
    if (!f->open(c_name, "cxw")) 
      return 0; 
    f->close(); 
 
    return my_hardlink(c_name, l_name) && this; 
  } 
 
  protected void _destruct() 
  { 
    rm(c_name); 
    rm(l_name); 
  } 
} 
 
object lock_file(string name) 
{ 
  return lock_key(name)->lock(); 
} 
 
object read_auth_data() 
{ 
  string fname = getenv("XAUTHORITY"); 
  if (!fname) 
    { 
      fname = getenv("HOME"); 
      if (!fname) 
        return 0; 
      fname = combine_path(fname, ".Xauthority"); 
    } 
 
  object key = lock_file(fname); 
  if (!key) 
    return 0; 
 
  string s = Stdio.read_file(fname); 
  key = 0; 
  if (!s) 
    return 0; 
 
  return auth_file(s); 
}