]> git.mxchange.org Git - friendica.git/blob - include/poller.php
a4bc607677c016e5ad36a7a8d0f538ed4243266b
[friendica.git] / include / poller.php
1 <?php
2
3
4         require_once('boot.php');
5
6         $a = new App;
7
8         @include('.htconfig.php');
9         require_once('dba.php');
10         $db = new dba($db_host, $db_user, $db_pass, $db_data);
11                 unset($db_host, $db_user, $db_pass, $db_data);
12
13         require_once('session.php');
14         require_once('datetime.php');
15         require_once('simplepie/simplepie.inc');
16         require_once('include/items.php');
17         require_once('include/Contact.php');
18
19         $a->set_baseurl(get_config('system','url'));
20
21         logger('poller: start');
22         
23         // run queue delivery process in the background
24
25         $php_path = ((x($a->config,'php_path') && strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
26         //proc_close(proc_open("\"$php_path\" \"include/queue.php\" &", array(), $foo));
27         proc_run($php_path,"include/queue.php");
28
29
30         $hub_update = false;
31         $force = false;
32
33         if(($argc > 1) && ($argv[1] == 'force'))
34                 $force = true;
35
36         if(($argc > 1) && intval($argv[1])) {
37                 $manual_id = intval($argv[1]);
38                 $force = true;
39         }
40
41         $sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
42
43         // 'stat' clause is a temporary measure until we have federation subscriptions working both directions
44         $contacts = q("SELECT * FROM `contact` 
45                 WHERE ( ( `network` = 'dfrn' AND ( `dfrn-id` != '' OR (`issued-id` != '' AND `duplex` = 1)))
46                 OR ( `network` IN ( 'stat', 'feed' ) AND `poll` != '' ))
47                 $sql_extra 
48                 AND `self` = 0 AND `blocked` = 0 AND `readonly` = 0 ORDER BY RAND()");
49
50         if(! count($contacts)){
51                 killme(); return;
52         }
53
54         foreach($contacts as $contact) {
55
56                 if($contact['priority'] || $contact['subhub']) {
57
58                         $hub_update = true;
59                         $update     = false;
60
61                         $t = $contact['last-update'];
62
63                         // We should be getting everything via a hub. But just to be sure, let's check once a day.
64                         // (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
65                         // This also lets us update our subscription to the hub, and add or replace hubs in case it
66                         // changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'. 
67
68
69                         if($contact['subhub']) {
70                                 $interval = get_config('system','pushpoll_frequency');
71                                 $contact['priority'] = (($interval !== false) ? intval($interval) : 3);
72                                 $hub_update = false;
73
74                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
75                                                 $hub_update = true;
76                         }
77
78
79                         /**
80                          * Based on $contact['priority'], should we poll this site now? Or later?
81                          */                     
82
83                         switch ($contact['priority']) {
84                                 case 5:
85                                         if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
86                                                 $update = true;
87                                         break;                                  
88                                 case 4:
89                                         if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
90                                                 $update = true;
91                                         break;
92                                 case 3:
93                                         if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
94                                                 $update = true;
95                                         break;
96                                 case 2:
97                                         if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
98                                                 $update = true;
99                                         break;
100                                 case 1:
101                                 default:
102                                         if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
103                                                 $update = true;
104                                         break;
105                         }
106                         if((! $update) && (! $force))
107                                 continue;
108                 }
109
110                 $importer_uid = $contact['uid'];
111
112                 $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
113                         intval($importer_uid)
114                 );
115                 if(! count($r))
116                         continue;
117
118                 $importer = $r[0];
119
120                 logger("poller: poll: IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
121
122                 $last_update = (($contact['last-update'] === '0000-00-00 00:00:00') 
123                         ? datetime_convert('UTC','UTC','now - 30 days', ATOM_TIME)
124                         : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
125                 );
126
127                 if($contact['network'] === 'dfrn') {
128
129                         $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
130
131                         if(intval($contact['duplex']) && $contact['dfrn-id'])
132                                 $idtosend = '0:' . $orig_id;
133                         if(intval($contact['duplex']) && $contact['issued-id'])
134                                 $idtosend = '1:' . $orig_id;            
135
136                         $url = $contact['poll'] . '?dfrn_id=' . $idtosend 
137                                 . '&dfrn_version=' . DFRN_PROTOCOL_VERSION 
138                                 . '&type=data&last_update=' . $last_update ;
139         
140                         $xml = fetch_url($url);
141
142                         logger('poller: handshake with url ' . $url . ' returns xml: ' . $xml, LOGGER_DATA);
143
144
145                         if(! $xml) {
146                                 logger("poller: $url appears to be dead - marking for death ");
147                                 // dead connection - might be a transient event, or this might
148                                 // mean the software was uninstalled or the domain expired. 
149                                 // Will keep trying for one month.
150                                 mark_for_death($contact);
151
152                                 // set the last-update so we don't keep polling
153
154                                 $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
155                                         dbesc(datetime_convert()),
156                                         intval($contact['id'])
157                                 );
158
159                                 continue;
160                         }
161
162                         if(! strstr($xml,'<?xml')) {
163                                 logger('poller: response from ' . $url . ' did not contain XML.');
164                                 $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
165                                         dbesc(datetime_convert()),
166                                         intval($contact['id'])
167                                 );
168                                 continue;
169                         }
170
171
172                         $res = simplexml_load_string($xml);
173
174                         if(intval($res->status) == 1) {
175                                 logger("poller: $url replied status 1 - marking for death ");
176
177                                 // we may not be friends anymore. Will keep trying for one month.
178                                 // set the last-update so we don't keep polling
179
180                                 $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
181                                         dbesc(datetime_convert()),
182                                         intval($contact['id'])
183                                 );
184
185                                 mark_for_death($contact);
186                         }
187                         else {
188                                 if($contact['term-date'] != '0000-00-00 00:00:00') {
189                                         logger("poller: $url back from the dead - removing mark for death");
190                                         unmark_for_death($contact);
191                                 }
192                         }
193
194                         if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
195                                 continue;
196
197                         $postvars = array();
198
199                         $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
200                         $challenge    = hex2bin((string) $res->challenge);
201
202                         $final_dfrn_id = '';
203
204                         if(($contact['duplex']) && strlen($contact['prvkey'])) {
205                                 openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
206                                 openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
207                         }
208                         else {
209                                 openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
210                                 openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
211                         }
212
213                         $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
214
215                         if(strpos($final_dfrn_id,':') == 1)
216                                 $final_dfrn_id = substr($final_dfrn_id,2);
217
218                         if($final_dfrn_id != $orig_id) {
219
220                                 // did not decode properly - cannot trust this site 
221                                 continue;
222                         }
223
224                         $postvars['dfrn_id'] = $idtosend;
225                         $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
226
227                         $xml = post_url($contact['poll'],$postvars);
228                 }
229                 else {
230                         // $contact['network'] !== 'dfrn'
231
232                         $xml = fetch_url($contact['poll']);
233                 }
234
235                 logger('poller: received xml : ' . $xml, LOGGER_DATA);
236
237                 if(! strlen($xml))
238                         continue;
239
240                 consume_feed($xml,$importer,$contact,$hub,1);
241
242                 // do it twice. Ensures that children of parents which may be later in the stream aren't tossed
243
244                 consume_feed($xml,$importer,$contact,$hub,1);
245
246
247                 if((strlen($hub)) && ($hub_update) 
248                         && (($contact['rel'] == REL_BUD) || (($contact['network'] === 'stat') && (! $contact['readonly'])))) {
249                         logger('poller: subscribing to hub(s) : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
250                         $hubs = explode(',', $hub);
251                         if(count($hubs)) {
252                                 foreach($hubs as $h) {
253                                         $h = trim($h);
254                                         if(! strlen($h))
255                                                 continue;
256                                         subscribe_to_hub($h,$importer,$contact);
257                                 }
258                         }
259                 }
260
261
262                 $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
263                         dbesc(datetime_convert()),
264                         intval($contact['id'])
265                 );
266
267                 // loop - next contact
268         }  
269                 
270         killme();
271
272
273