예제 #1
0
function thing_init(&$a)
{
    if (!local_channel()) {
        return;
    }
    $channel = App::get_channel();
    $term_hash = $_REQUEST['term_hash'] ? $_REQUEST['term_hash'] : '';
    $name = escape_tags($_REQUEST['term']);
    $verb = escape_tags($_REQUEST['verb']);
    $activity = intval($_REQUEST['activity']);
    $profile_guid = escape_tags($_REQUEST['profile_assign']);
    $url = $_REQUEST['link'];
    $photo = $_REQUEST['img'];
    $hash = random_string();
    $verbs = obj_verbs();
    /**
     * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" 
     * We use the first person form when creating an activity, but the third person for use in activities
     * @FIXME There is no accounting for verb gender for languages where this is significant. We may eventually
     * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module.
     */
    $translated_verb = $verbs[$verb][1];
    /*
     * The site administrator can do things that normals cannot.
     * This is restricted because it will likely cause
     * an activitystreams protocol violation and the activity might
     * choke in some other network and result in unnecessary 
     * support requests. It isn't because we're trying to be heavy-handed
     * about what you can and can't do. 
     */
    if (!$translated_verb) {
        if (is_site_admin()) {
            $translated_verb = $verb;
        }
    }
    /*
     * Things, objects: We do not provide definite (a, an) or indefinite (the) articles or singular/plural designators
     * That needs to be specified in your thing. e.g. Mike has "a carrot", Greg wants "balls", Bob likes "the Boston Red Sox".  
     */
    /*
     * Future work on this module might produce more complex activities with targets, e.g. Phillip likes Karen's moustache
     * and to describe other non-thing objects like channels, such as Karl wants Susan - where Susan represents a channel profile.
     */
    if (!$name || !$translated_verb) {
        return;
    }
    $acl = new Zotlabs\Access\AccessList($channel);
    if (array_key_exists('contact_allow', $_REQUEST) || array_key_exists('group_allow', $_REQUEST) || array_key_exists('contact_deny', $_REQUEST) || array_key_exists('group_deny', $_REQUEST)) {
        $acl->set_from_array($_REQUEST);
    }
    $x = $acl->get();
    if ($term_hash) {
        $t = q("select * from obj where obj_obj = '%s' and obj_channel = %d limit 1", dbesc($term_hash), intval(local_channel()));
        if (!$t) {
            notice(t('Item not found.') . EOL);
            return;
        }
        $orig_record = $t[0];
        if ($photo != $orig_record['obj_imgurl']) {
            $arr = import_xchan_photo($photo, get_observer_hash(), true);
            $local_photo = $arr[0];
            $local_photo_type = $arr[3];
        } else {
            $local_photo = $orig_record['obj_imgurl'];
        }
        $r = q("update obj set obj_term = '%s', obj_url = '%s', obj_imgurl = '%s', obj_edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where obj_obj = '%s' and obj_channel = %d ", dbesc($name), dbesc($url ? $url : z_root() . '/thing/' . $term_hash), dbesc($local_photo), dbesc(datetime_convert()), dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), dbesc($term_hash), intval(local_channel()));
        info(t('Thing updated') . EOL);
        $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", intval(local_channel()), dbesc($term_hash));
        if ($r) {
            build_sync_packet(0, array('obj' => $r));
        }
        return;
    }
    $sql = $profile_guid ? " and profile_guid = '" . dbesc($profile_guid) . "' " : " and is_default = 1 ";
    $p = q("select profile_guid, is_default from profile where uid = %d {$sql} limit 1", intval(local_channel()));
    if ($p) {
        $profile = $p[0];
    } else {
        return;
    }
    $local_photo = null;
    if ($photo) {
        $arr = import_xchan_photo($photo, get_observer_hash(), true);
        $local_photo = $arr[0];
        $local_photo_type = $arr[3];
    }
    $created = datetime_convert();
    $url = $url ? $url : z_root() . '/thing/' . $hash;
    $r = q("insert into obj ( obj_page, obj_verb, obj_type, obj_channel, obj_obj, obj_term, obj_url, obj_imgurl, obj_created, obj_edited, allow_cid, allow_gid, deny_cid, deny_gid ) values ('%s','%s', %d, %d, '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') ", dbesc($profile['profile_guid']), dbesc($verb), intval(TERM_OBJ_THING), intval(local_channel()), dbesc($hash), dbesc($name), dbesc($url), dbesc($photo ? $local_photo : ''), dbesc($created), dbesc($created), dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']));
    if (!$r) {
        notice(t('Object store: failed'));
        return;
    }
    info(t('Thing added'));
    $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", intval(local_channel()), dbesc($hash));
    if ($r) {
        build_sync_packet(0, array('obj' => $r));
    }
    if ($activity) {
        $arr = array();
        $links = array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => $url));
        if ($local_photo) {
            $links[] = array('rel' => 'photo', 'type' => $local_photo_type, 'href' => $local_photo);
        }
        $objtype = ACTIVITY_OBJ_THING;
        $obj = json_encode(array('type' => $objtype, 'id' => $url, 'link' => $links, 'title' => $name, 'content' => $name));
        $bodyverb = str_replace('OBJ: ', '', t('OBJ: %1$s %2$s %3$s'));
        $arr['owner_xchan'] = $channel['channel_hash'];
        $arr['author_xchan'] = $channel['channel_hash'];
        $arr['item_origin'] = 1;
        $arr['item_wall'] = 1;
        $arr['item_thread_top'] = 1;
        $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]';
        $plink = '[zrl=' . $url . ']' . $name . '[/zrl]';
        $arr['body'] = sprintf($bodyverb, $ulink, $translated_verb, $plink);
        if ($local_photo) {
            $arr['body'] .= "\n\n[zmg]" . $local_photo . "[/zmg]";
        }
        $arr['verb'] = $verb;
        $arr['obj_type'] = $objtype;
        $arr['object'] = $obj;
        if (!$profile['is_default']) {
            $arr['item_private'] = true;
            $str = '';
            $r = q("select abook_xchan from abook where abook_channel = %d and abook_profile = '%s'", intval(local_channel()), dbesc($profile_guid));
            if ($r) {
                $arr['allow_cid'] = '';
                foreach ($r as $rr) {
                    $arr['allow_cid'] .= '<' . $rr['abook_xchan'] . '>';
                }
            } else {
                $arr['allow_cid'] = '<' . get_observer_hash() . '>';
            }
        }
        $ret = post_activity_item($arr);
    }
}
예제 #2
0
파일: zot.php 프로젝트: 23n/hubzilla
/**
 * @brief Takes an associative array of a fetched discovery packet and updates
 *   all internal data structures which need to be updated as a result.
 *
 * @param array $arr => json_decoded discovery packet
 * @param int $ud_flags
 *    Determines whether to create a directory update record if any changes occur, default is UPDATE_FLAGS_UPDATED
 *    $ud_flags = UPDATE_FLAGS_FORCED indicates a forced refresh where we unconditionally create a directory update record
 *      this typically occurs once a month for each channel as part of a scheduled ping to notify the directory
 *      that the channel still exists
 * @param array $ud_arr
 *    If set [typically by update_directory_entry()] indicates a specific update table row and more particularly
 *    contains a particular address (ud_addr) which needs to be updated in that table.
 *
 * @return associative array
 *   * \e boolean \b success boolean true or false
 *   * \e string \b message (optional) error string only if success is false
 */
function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null)
{
    call_hooks('import_xchan', $arr);
    $ret = array('success' => false);
    $dirmode = intval(get_config('system', 'directory_mode'));
    $changed = false;
    $what = '';
    if (!(is_array($arr) && array_key_exists('success', $arr) && $arr['success'])) {
        logger('import_xchan: invalid data packet: ' . print_r($arr, true));
        $ret['message'] = t('Invalid data packet');
        return $ret;
    }
    if (!($arr['guid'] && $arr['guid_sig'])) {
        logger('import_xchan: no identity information provided. ' . print_r($arr, true));
        return $ret;
    }
    $xchan_hash = make_xchan_hash($arr['guid'], $arr['guid_sig']);
    $arr['hash'] = $xchan_hash;
    $import_photos = false;
    if (!rsa_verify($arr['guid'], base64url_decode($arr['guid_sig']), $arr['key'])) {
        logger('import_xchan: Unable to verify channel signature for ' . $arr['address']);
        $ret['message'] = t('Unable to verify channel signature');
        return $ret;
    }
    logger('import_xchan: ' . $xchan_hash, LOGGER_DEBUG);
    $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($xchan_hash));
    if (!array_key_exists('connect_url', $arr)) {
        $arr['connect_url'] = '';
    }
    if (strpos($arr['address'], '/') !== false) {
        $arr['address'] = substr($arr['address'], 0, strpos($arr['address'], '/'));
    }
    if ($r) {
        if ($r[0]['xchan_photo_date'] != $arr['photo_updated']) {
            $import_photos = true;
        }
        // if we import an entry from a site that's not ours and either or both of us is off the grid - hide the entry.
        /** @TODO: check if we're the same directory realm, which would mean we are allowed to see it */
        $dirmode = get_config('system', 'directory_mode');
        if (($arr['site']['directory_mode'] === 'standalone' || $dirmode & DIRECTORY_MODE_STANDALONE) && $arr['site']['url'] != z_root()) {
            $arr['searchable'] = false;
        }
        $hidden = 1 - intval($arr['searchable']);
        $hidden_changed = $adult_changed = $deleted_changed = $pubforum_changed = 0;
        if (intval($r[0]['xchan_hidden']) != 1 - intval($arr['searchable'])) {
            $hidden_changed = 1;
        }
        if (intval($r[0]['xchan_selfcensored']) != intval($arr['adult_content'])) {
            $adult_changed = 1;
        }
        if (intval($r[0]['xchan_deleted']) != intval($arr['deleted'])) {
            $deleted_changed = 1;
        }
        if (intval($r[0]['xchan_pubforum']) != intval($arr['public_forum'])) {
            $pubforum_changed = 1;
        }
        if ($r[0]['xchan_name_date'] != $arr['name_updated'] || $r[0]['xchan_connurl'] != $arr['connections_url'] || $r[0]['xchan_addr'] != $arr['address'] || $r[0]['xchan_follow'] != $arr['follow_url'] || $r[0]['xchan_connpage'] != $arr['connect_url'] || $r[0]['xchan_url'] != $arr['url'] || $hidden_changed || $adult_changed || $deleted_changed || $pubforum_changed) {
            $rup = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s', \n\t\t\t\txchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_pubforum = %d, \n\t\t\t\txchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s'", dbesc($arr['name'] ? $arr['name'] : '-'), dbesc($arr['name_updated']), dbesc($arr['connections_url']), dbesc($arr['follow_url']), dbesc($arr['connect_url']), intval(1 - intval($arr['searchable'])), intval($arr['adult_content']), intval($arr['deleted']), intval($arr['public_forum']), dbesc($arr['address']), dbesc($arr['url']), dbesc($xchan_hash));
            logger('import_xchan: update: existing: ' . print_r($r[0], true), LOGGER_DATA);
            logger('import_xchan: update: new: ' . print_r($arr, true), LOGGER_DATA);
            $what .= 'xchan ';
            $changed = true;
        }
    } else {
        $import_photos = true;
        if (($arr['site']['directory_mode'] === 'standalone' || $dirmode & DIRECTORY_MODE_STANDALONE) && $arr['site']['url'] != z_root()) {
            $arr['searchable'] = false;
        }
        $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,\n\t\t\t\txchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_selfcensored, xchan_deleted, xchan_pubforum )\n\t\t\t\tvalues ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d) ", dbesc($xchan_hash), dbesc($arr['guid']), dbesc($arr['guid_sig']), dbesc($arr['key']), dbesc($arr['photo_mimetype']), dbesc($arr['photo']), dbesc($arr['address']), dbesc($arr['url']), dbesc($arr['connections_url']), dbesc($arr['follow_url']), dbesc($arr['connect_url']), dbesc($arr['name'] ? $arr['name'] : '-'), dbesc('zot'), dbescdate($arr['photo_updated']), dbescdate($arr['name_updated']), intval(1 - intval($arr['searchable'])), intval($arr['adult_content']), intval($arr['deleted']), intval($arr['public_forum']));
        $what .= 'new_xchan';
        $changed = true;
    }
    if ($import_photos) {
        require_once 'include/photo/photo_driver.php';
        // see if this is a channel clone that's hosted locally - which we treat different from other xchans/connections
        $local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1", dbesc($xchan_hash));
        if ($local) {
            $ph = z_fetch_url($arr['photo'], true);
            if ($ph['success']) {
                $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
                if ($hash) {
                    // unless proven otherwise
                    $is_default_profile = 1;
                    $profile = q("select is_default from profile where aid = %d and uid = %d limit 1", intval($local[0]['channel_account_id']), intval($local[0]['channel_id']));
                    if ($profile) {
                        if (!intval($profile[0]['is_default'])) {
                            $is_default_profile = 0;
                        }
                    }
                    // If setting for the default profile, unset the profile photo flag from any other photos I own
                    if ($is_default_profile) {
                        q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), dbesc($hash), intval($local[0]['channel_account_id']), intval($local[0]['channel_id']));
                    }
                }
                // reset the names in case they got messed up when we had a bug in this function
                $photos = array(z_root() . '/photo/profile/l/' . $local[0]['channel_id'], z_root() . '/photo/profile/m/' . $local[0]['channel_id'], z_root() . '/photo/profile/s/' . $local[0]['channel_id'], $arr['photo_mimetype'], false);
            }
        } else {
            $photos = import_xchan_photo($arr['photo'], $xchan_hash);
        }
        if ($photos) {
            if ($photos[4]) {
                // importing the photo failed somehow. Leave the photo_date alone so we can try again at a later date.
                // This often happens when somebody joins the matrix with a bad cert.
                $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'\n\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($xchan_hash));
            } else {
                $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'\n\t\t\t\t\twhere xchan_hash = '%s'", dbescdate(datetime_convert('UTC', 'UTC', $arr['photo_updated'])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($xchan_hash));
            }
            $what .= 'photo ';
            $changed = true;
        }
    }
    // what we are missing for true hub independence is for any changes in the primary hub to
    // get reflected not only in the hublocs, but also to update the URLs and addr in the appropriate xchan
    $s = sync_locations($arr, $arr);
    if ($s) {
        if ($s['change_message']) {
            $what .= $s['change_message'];
        }
        if ($s['changed']) {
            $changed = $s['changed'];
        }
        if ($s['message']) {
            $ret['message'] .= $s['message'];
        }
    }
    // Which entries in the update table are we interested in updating?
    $address = $ud_arr && $ud_arr['ud_addr'] ? $ud_arr['ud_addr'] : $arr['address'];
    // Are we a directory server of some kind?
    $other_realm = false;
    $realm = get_directory_realm();
    if (array_key_exists('site', $arr) && array_key_exists('realm', $arr['site']) && strpos($arr['site']['realm'], $realm) === false) {
        $other_realm = true;
    }
    if ($dirmode != DIRECTORY_MODE_NORMAL) {
        // We're some kind of directory server. However we can only add directory information
        // if the entry is in the same realm (or is a sub-realm). Sub-realms are denoted by
        // including the parent realm in the name. e.g. 'RED_GLOBAL:foo' would allow an entry to
        // be in directories for the local realm (foo) and also the RED_GLOBAL realm.
        if (array_key_exists('profile', $arr) && is_array($arr['profile']) && !$other_realm) {
            $profile_changed = import_directory_profile($xchan_hash, $arr['profile'], $address, $ud_flags, 1);
            if ($profile_changed) {
                $what .= 'profile ';
                $changed = true;
            }
        } else {
            logger('import_xchan: profile not available - hiding');
            // they may have made it private
            $r = q("delete from xprof where xprof_hash = '%s'", dbesc($xchan_hash));
            $r = q("delete from xtag where xtag_hash = '%s' and xtag_flags = 0", dbesc($xchan_hash));
        }
    }
    if (array_key_exists('site', $arr) && is_array($arr['site'])) {
        $profile_changed = import_site($arr['site'], $arr['key']);
        if ($profile_changed) {
            $what .= 'site ';
            $changed = true;
        }
    }
    if ($changed || $ud_flags == UPDATE_FLAGS_FORCED) {
        $guid = random_string() . '@' . get_app()->get_hostname();
        update_modtime($xchan_hash, $guid, $address, $ud_flags);
        logger('import_xchan: changed: ' . $what, LOGGER_DEBUG);
    } elseif (!$ud_flags) {
        // nothing changed but we still need to update the updates record
        q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d)>0 ", intval(UPDATE_FLAGS_UPDATED), dbesc($address), intval(UPDATE_FLAGS_UPDATED));
    }
    if (!x($ret, 'message')) {
        $ret['success'] = true;
        $ret['hash'] = $xchan_hash;
    }
    logger('import_xchan: result: ' . print_r($ret, true), LOGGER_DATA);
    return $ret;
}
예제 #3
0
function diaspora_discover(&$a, &$b)
{
    require_once 'include/network.php';
    $result = array();
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $dfrn = false;
    $x = old_webfinger($webbie);
    if ($x) {
        logger('old_webfinger: ' . print_r($x, true));
        foreach ($x as $link) {
            if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                $dfrn = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'salmon') {
                $notify = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                $poll = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                $hcard = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                $profile = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                $poco = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                $diaspora_base = unamp($link['@attributes']['href']);
                $diaspora = true;
            }
            if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                $diaspora_guid = unamp($link['@attributes']['href']);
                $diaspora = true;
            }
            if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                if (strstr($diaspora_key, 'RSA ')) {
                    $pubkey = rsatopem($diaspora_key);
                } else {
                    $pubkey = $diaspora_key;
                }
                $diaspora = true;
            }
        }
        if ($diaspora && $diaspora_base && $diaspora_guid) {
            $guid = $diaspora_guid;
            $diaspora_base = trim($diaspora_base, '/');
            $notify = $diaspora_base . '/receive';
            if (strpos($webbie, '@')) {
                $addr = str_replace('acct:', '', $webbie);
                $hostname = substr($webbie, strpos($webbie, '@') + 1);
            }
            $network = 'diaspora';
            // until we get a dfrn layer, we'll use diaspora protocols for Friendica,
            // but give it a different network so we can go back and fix these when we get proper support.
            // It really should be just 'friendica' but we also want to distinguish
            // between Friendica sites that we can use D* protocols with and those we can't.
            // Some Friendica sites will have Diaspora disabled.
            if ($dfrn) {
                $network = 'friendica-over-diaspora';
            }
            if ($hcard) {
                $vcard = scrape_vcard($hcard);
                $vcard['nick'] = substr($webbie, 0, strpos($webbie, '@'));
                if (!$vcard['fn']) {
                    $vcard['fn'] = $webbie;
                }
            }
            $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($addr));
            /**
             *
             * Diaspora communications are notoriously unreliable and receiving profile update messages (indeed any messages) 
             * are pretty much random luck. We'll check the timestamp of the xchan_name_date at a higher level and refresh
             * this record once a month; because if you miss a profile update message and they update their profile photo or name 
             * you're otherwise stuck with stale info until they change their profile again - which could be years from now. 
             *
             */
            if ($r) {
                $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1", dbesc($vcard['fn']), dbesc($network), dbesc(datetime_convert()), dbesc($addr));
            } else {
                $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($addr), dbesc($guid), dbesc($pubkey), dbesc($addr), dbesc($profile), dbesc($vcard['fn']), dbesc($network), dbescdate(datetime_convert()));
            }
            $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($webbie));
            if (!$r) {
                $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)", dbesc($guid), dbesc($addr), dbesc($addr), dbesc($network), dbesc(trim($diaspora_base, '/')), dbesc($hostname), dbesc($notify), dbescdate(datetime_convert()));
            }
            $photos = import_xchan_photo($vcard['photo'], $addr);
            $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbescdate(datetime_convert('UTC', 'UTC', $arr['photo_updated'])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($addr));
            return true;
        }
        return false;
        /*
        	$vcard['fn'] = notags($vcard['fn']);
        	$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
        	$result['name'] = $vcard['fn'];
        	$result['nick'] = $vcard['nick'];
        	$result['guid'] = $guid;
        	$result['url'] = $profile;
        	$result['hostname'] = $hostname;
        	$result['addr'] = $addr;
        	$result['batch'] = $batch;
        	$result['notify'] = $notify;
        	$result['poll'] = $poll;
        	$result['request'] = $request;
        	$result['confirm'] = $confirm;
        	$result['poco'] = $poco;
        	$result['photo'] = $vcard['photo'];
        	$result['priority'] = $priority;
        	$result['network'] = $network;
        	$result['alias'] = $alias;
        	$result['pubkey'] = $pubkey;
        	logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
        	return $result;
        */
        /* Sample Diaspora result.
        
        Array
        (
        	[name] => Mike Macgirvin
        	[nick] => macgirvin
        	[guid] => a9174a618f8d269a
        	[url] => https://joindiaspora.com/u/macgirvin
        	[hostname] => joindiaspora.com
        	[addr] => macgirvin@joindiaspora.com
        	[batch] => 
        	[notify] => https://joindiaspora.com/receive
        	[poll] => https://joindiaspora.com/public/macgirvin.atom
        	[request] => 
        	[confirm] => 
        	[poco] => 
        	[photo] => https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_fec4e6eef13ae5e56207.jpg
        	[priority] => 
        	[network] => diaspora
        	[alias] => 
        	[pubkey] => -----BEGIN PUBLIC KEY-----
        MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtihtyIuRDWkDpCA+I1UaQ
        jI4S7k625+A7EEJm+pL2ZVSJxeCKiFeEgHBQENjLMNNm8l8F6blxgQqE6ZJ9Spa7f
        tlaXYTRCrfxKzh02L3hR7sNA+JS/nXJaUAIo+IwpIEspmcIRbD9GB7Wv/rr+M28uH
        31EeYyDz8QL6InU/bJmnCdFvmEMBQxJOw1ih9tQp7UNJAbUMCje0WYFzBz7sfcaHL
        OyYcCOqOCBLdGucUoJzTQ9iDBVzB8j1r1JkIHoEb2moUoKUp+tkCylNfd/3IVELF9
        7w1Qjmit3m50OrJk2DQOXvCW9KQxaQNdpRPSwhvemIt98zXSeyZ1q/YjjOwG0DWDq
        AF8aLj3/oQaZndTPy/6tMiZogKaijoxj8xFLuPYDTw5VpKquriVC0z8oxyRbv4t9v
        8JZZ9BXqzmayvY3xZGGp8NulrfjW+me2bKh0/df1aHaBwpZdDTXQ6kqAiS2FfsuPN
        vg57fhfHbL1yJ4oDbNNNeI0kJTGchXqerr8C20khU/cQ2Xt31VyEZtnTB665Ceugv
        kp3t2qd8UpAVKl430S5Quqx2ymfUIdxdW08CEjnoRNEL3aOWOXfbf4gSVaXmPCR4i
        LSIeXnd14lQYK/uxW/8cTFjcmddsKxeXysoQxbSa9VdDK+KkpZdgYXYrTTofXs6v+
        4afAEhRaaY+MCAwEAAQ==
        -----END PUBLIC KEY-----
        
        )
        */
    }
}
예제 #4
0
 function import_account($account_id)
 {
     if (!$account_id) {
         logger("import_account: No account ID supplied");
         return;
     }
     $max_identities = account_service_class_fetch($account_id, 'total_identities');
     $max_friends = account_service_class_fetch($account_id, 'total_channels');
     $max_feeds = account_service_class_fetch($account_id, 'total_feeds');
     if ($max_identities !== false) {
         $r = q("select channel_id from channel where channel_account_id = %d", intval($account_id));
         if ($r && count($r) > $max_identities) {
             notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL);
             return;
         }
     }
     $data = null;
     $seize = x($_REQUEST, 'make_primary') ? intval($_REQUEST['make_primary']) : 0;
     $import_posts = x($_REQUEST, 'import_posts') ? intval($_REQUEST['import_posts']) : 0;
     $src = $_FILES['filename']['tmp_name'];
     $filename = basename($_FILES['filename']['name']);
     $filesize = intval($_FILES['filename']['size']);
     $filetype = $_FILES['filename']['type'];
     $completed = array_key_exists('import_step', $_SESSION) ? intval($_SESSION['import_step']) : 0;
     if ($completed) {
         logger('saved import step: ' . $_SESSION['import_step']);
     }
     if ($src) {
         // This is OS specific and could also fail if your tmpdir isn't very large
         // mostly used for Diaspora which exports gzipped files.
         if (strpos($filename, '.gz')) {
             @rename($src, $src . '.gz');
             @system('gunzip ' . escapeshellarg($src . '.gz'));
         }
         if ($filesize) {
             $data = @file_get_contents($src);
         }
         unlink($src);
     }
     if (!$src) {
         $old_address = x($_REQUEST, 'old_address') ? $_REQUEST['old_address'] : '';
         if (!$old_address) {
             logger('mod_import: nothing to import.');
             notice(t('Nothing to import.') . EOL);
             return;
         }
         $email = x($_REQUEST, 'email') ? $_REQUEST['email'] : '';
         $password = x($_REQUEST, 'password') ? $_REQUEST['password'] : '';
         $channelname = substr($old_address, 0, strpos($old_address, '@'));
         $servername = substr($old_address, strpos($old_address, '@') + 1);
         $scheme = 'https://';
         $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname;
         if ($import_posts) {
             $api_path .= '&posts=1';
         }
         $binary = false;
         $redirects = 0;
         $opts = array('http_auth' => $email . ':' . $password);
         $url = $scheme . $servername . $api_path;
         $ret = z_fetch_url($url, $binary, $redirects, $opts);
         if (!$ret['success']) {
             $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts);
         }
         if ($ret['success']) {
             $data = $ret['body'];
         } else {
             notice(t('Unable to download data from old server') . EOL);
         }
     }
     if (!$data) {
         logger('mod_import: empty file.');
         notice(t('Imported file is empty.') . EOL);
         return;
     }
     $data = json_decode($data, true);
     //	logger('import: data: ' . print_r($data,true));
     //	print_r($data);
     if (array_key_exists('user', $data) && array_key_exists('version', $data)) {
         require_once 'include/Import/import_diaspora.php';
         import_diaspora($data);
         return;
     }
     $moving = false;
     if (array_key_exists('compatibility', $data) && array_key_exists('database', $data['compatibility'])) {
         $v1 = substr($data['compatibility']['database'], -4);
         $v2 = substr(DB_UPDATE_VERSION, -4);
         if ($v2 > $v1) {
             $t = sprintf(t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1);
             notice($t);
         }
         if (array_key_exists('server_role', $data['compatibility']) && $data['compatibility']['server_role'] == 'basic') {
             $moving = true;
         }
     }
     if ($moving) {
         $seize = 1;
     }
     // import channel
     $relocate = array_key_exists('relocate', $data) ? $data['relocate'] : null;
     if (array_key_exists('channel', $data)) {
         if ($completed < 1) {
             $channel = import_channel($data['channel'], $account_id, $seize);
         } else {
             $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), dbesc($channel['channel_guid']));
             if ($r) {
                 $channel = $r[0];
             }
         }
         if (!$channel) {
             logger('mod_import: channel not found. ', print_r($channel, true));
             notice(t('Cloned channel not found. Import failed.') . EOL);
             return;
         }
     }
     if (!$channel) {
         $channel = \App::get_channel();
     }
     if (!$channel) {
         logger('mod_import: channel not found. ', print_r($channel, true));
         notice(t('No channel. Import failed.') . EOL);
         return;
     }
     if ($completed < 2) {
         if (is_array($data['config'])) {
             import_config($channel, $data['config']);
         }
         logger('import step 2');
         $_SESSION['import_step'] = 2;
     }
     if ($completed < 3) {
         if ($data['photo']) {
             require_once 'include/photo/photo_driver.php';
             import_channel_photo(base64url_decode($data['photo']['data']), $data['photo']['type'], $account_id, $channel['channel_id']);
         }
         if (is_array($data['profile'])) {
             import_profiles($channel, $data['profile']);
         }
         logger('import step 3');
         $_SESSION['import_step'] = 3;
     }
     if ($completed < 4) {
         if (is_array($data['hubloc']) && !$moving) {
             import_hublocs($channel, $data['hubloc'], $seize);
         }
         logger('import step 4');
         $_SESSION['import_step'] = 4;
     }
     if ($completed < 5) {
         // create new hubloc for the new channel at this site
         $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, \n\t\t\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )\n\t\t\t\tvalues ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_hash']), dbesc(channel_reddress($channel)), dbesc('zot'), intval($seize ? 1 : 0), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $channel['channel_prvkey']))), dbesc(\App::get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey')));
         // reset the original primary hubloc if it is being seized
         if ($seize) {
             $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", dbesc($channel['channel_hash']), dbesc(z_root()));
         }
         logger('import step 5');
         $_SESSION['import_step'] = 5;
     }
     if ($completed < 6) {
         // import xchans and contact photos
         if ($seize) {
             // replace any existing xchan we may have on this site if we're seizing control
             $r = q("delete from xchan where xchan_hash = '%s'", dbesc($channel['channel_hash']));
             $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )", dbesc($channel['channel_hash']), dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_pubkey']), dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']), dbesc(channel_reddress($channel)), dbesc(z_root() . '/channel/' . $channel['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $channel['channel_address']), dbesc($channel['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), 0, 0, 0, 0, 0, 0, 0);
         }
         logger('import step 6');
         $_SESSION['import_step'] = 6;
     }
     if ($completed < 7) {
         $xchans = $data['xchan'];
         if ($xchans) {
             foreach ($xchans as $xchan) {
                 $hash = make_xchan_hash($xchan['xchan_guid'], $xchan['xchan_guid_sig']);
                 if ($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
                     logger('forged xchan: ' . print_r($xchan, true));
                     continue;
                 }
                 if (!array_key_exists('xchan_hidden', $xchan)) {
                     $xchan['xchan_hidden'] = $xchan['xchan_flags'] & 0x1 ? 1 : 0;
                     $xchan['xchan_orphan'] = $xchan['xchan_flags'] & 0x2 ? 1 : 0;
                     $xchan['xchan_censored'] = $xchan['xchan_flags'] & 0x4 ? 1 : 0;
                     $xchan['xchan_selfcensored'] = $xchan['xchan_flags'] & 0x8 ? 1 : 0;
                     $xchan['xchan_system'] = $xchan['xchan_flags'] & 0x10 ? 1 : 0;
                     $xchan['xchan_pubforum'] = $xchan['xchan_flags'] & 0x20 ? 1 : 0;
                     $xchan['xchan_deleted'] = $xchan['xchan_flags'] & 0x1000 ? 1 : 0;
                 }
                 $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($xchan['xchan_hash']));
                 if ($r) {
                     continue;
                 }
                 dbesc_array($xchan);
                 $r = dbq("INSERT INTO xchan (`" . implode("`, `", array_keys($xchan)) . "`) VALUES ('" . implode("', '", array_values($xchan)) . "')");
                 require_once 'include/photo/photo_driver.php';
                 $photos = import_xchan_photo($xchan['xchan_photo_l'], $xchan['xchan_hash']);
                 if ($photos[4]) {
                     $photodate = NULL_DATE;
                 } else {
                     $photodate = $xchan['xchan_photo_date'];
                 }
                 $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'\n\t\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($photodate), dbesc($xchan['xchan_hash']));
             }
         }
         logger('import step 7');
         $_SESSION['import_step'] = 7;
     }
     // FIXME - ensure we have an xchan if somebody is trying to pull a fast one
     if ($completed < 8) {
         $friends = 0;
         $feeds = 0;
         // import contacts
         $abooks = $data['abook'];
         if ($abooks) {
             foreach ($abooks as $abook) {
                 $abook_copy = $abook;
                 $abconfig = null;
                 if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) {
                     $abconfig = $abook['abconfig'];
                 }
                 unset($abook['abook_id']);
                 unset($abook['abook_rating']);
                 unset($abook['abook_rating_text']);
                 unset($abook['abconfig']);
                 unset($abook['abook_their_perms']);
                 unset($abook['abook_my_perms']);
                 $abook['abook_account'] = $account_id;
                 $abook['abook_channel'] = $channel['channel_id'];
                 if (!array_key_exists('abook_blocked', $abook)) {
                     $abook['abook_blocked'] = $abook['abook_flags'] & 0x1 ? 1 : 0;
                     $abook['abook_ignored'] = $abook['abook_flags'] & 0x2 ? 1 : 0;
                     $abook['abook_hidden'] = $abook['abook_flags'] & 0x4 ? 1 : 0;
                     $abook['abook_archived'] = $abook['abook_flags'] & 0x8 ? 1 : 0;
                     $abook['abook_pending'] = $abook['abook_flags'] & 0x10 ? 1 : 0;
                     $abook['abook_unconnected'] = $abook['abook_flags'] & 0x20 ? 1 : 0;
                     $abook['abook_self'] = $abook['abook_flags'] & 0x80 ? 1 : 0;
                     $abook['abook_feed'] = $abook['abook_flags'] & 0x100 ? 1 : 0;
                 }
                 if ($abook['abook_self']) {
                     $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role');
                     if ($role === 'forum' || $abook['abook_my_perms'] & PERMS_W_TAGWALL) {
                         q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ", dbesc($abook['abook_xchan']));
                     }
                 } else {
                     if ($max_friends !== false && $friends > $max_friends) {
                         continue;
                     }
                     if ($max_feeds !== false && intval($abook['abook_feed']) && $feeds > $max_feeds) {
                         continue;
                     }
                 }
                 dbesc_array($abook);
                 $r = dbq("INSERT INTO abook (`" . implode("`, `", array_keys($abook)) . "`) VALUES ('" . implode("', '", array_values($abook)) . "')");
                 $friends++;
                 if (intval($abook['abook_feed'])) {
                     $feeds++;
                 }
                 translate_abook_perms_inbound($channel, $abook_copy);
                 if ($abconfig) {
                     // @fixme does not handle sync of del_abconfig
                     foreach ($abconfig as $abc) {
                         set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']);
                     }
                 }
             }
         }
         logger('import step 8');
         $_SESSION['import_step'] = 8;
     }
     if ($completed < 9) {
         $groups = $data['group'];
         if ($groups) {
             $saved = array();
             foreach ($groups as $group) {
                 $saved[$group['hash']] = array('old' => $group['id']);
                 if (array_key_exists('name', $group)) {
                     $group['gname'] = $group['name'];
                     unset($group['name']);
                 }
                 unset($group['id']);
                 $group['uid'] = $channel['channel_id'];
                 dbesc_array($group);
                 $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) . "`) VALUES ('" . implode("', '", array_values($group)) . "')");
             }
             $r = q("select * from `groups` where uid = %d", intval($channel['channel_id']));
             if ($r) {
                 foreach ($r as $rr) {
                     $saved[$rr['hash']]['new'] = $rr['id'];
                 }
             }
         }
         $group_members = $data['group_member'];
         if ($group_members) {
             foreach ($group_members as $group_member) {
                 unset($group_member['id']);
                 $group_member['uid'] = $channel['channel_id'];
                 foreach ($saved as $x) {
                     if ($x['old'] == $group_member['gid']) {
                         $group_member['gid'] = $x['new'];
                     }
                 }
                 dbesc_array($group_member);
                 $r = dbq("INSERT INTO group_member (`" . implode("`, `", array_keys($group_member)) . "`) VALUES ('" . implode("', '", array_values($group_member)) . "')");
             }
         }
         logger('import step 9');
         $_SESSION['import_step'] = 9;
     }
     if (is_array($data['obj'])) {
         import_objs($channel, $data['obj']);
     }
     if (is_array($data['likes'])) {
         import_likes($channel, $data['likes']);
     }
     if (is_array($data['app'])) {
         import_apps($channel, $data['app']);
     }
     if (is_array($data['chatroom'])) {
         import_chatrooms($channel, $data['chatroom']);
     }
     if (is_array($data['conv'])) {
         import_conv($channel, $data['conv']);
     }
     if (is_array($data['mail'])) {
         import_mail($channel, $data['mail']);
     }
     if (is_array($data['event'])) {
         import_events($channel, $data['event']);
     }
     if (is_array($data['event_item'])) {
         import_items($channel, $data['event_item'], false, $relocate);
     }
     if (is_array($data['menu'])) {
         import_menus($channel, $data['menu']);
     }
     $addon = array('channel' => $channel, 'data' => $data);
     call_hooks('import_channel', $addon);
     $saved_notification_flags = notifications_off($channel['channel_id']);
     if ($import_posts && array_key_exists('item', $data) && $data['item']) {
         import_items($channel, $data['item'], false, $relocate);
     }
     notifications_on($channel['channel_id'], $saved_notification_flags);
     if (array_key_exists('item_id', $data) && $data['item_id']) {
         import_item_ids($channel, $data['item_id']);
     }
     // FIXME - ensure we have a self entry if somebody is trying to pull a fast one
     // send out refresh requests
     // notify old server that it may no longer be primary.
     \Zotlabs\Daemon\Master::Summon(array('Notifier', 'location', $channel['channel_id']));
     // This will indirectly perform a refresh_all *and* update the directory
     \Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id']));
     notice(t('Import completed.') . EOL);
     change_channel($channel['channel_id']);
     unset($_SESSION['import_step']);
     goaway(z_root() . '/network');
 }
예제 #5
0
파일: Cron.php 프로젝트: phellmes/hubzilla
 public static function run($argc, $argv)
 {
     $maxsysload = intval(get_config('system', 'maxloadavg'));
     if ($maxsysload < 1) {
         $maxsysload = 50;
     }
     if (function_exists('sys_getloadavg')) {
         $load = sys_getloadavg();
         if (intval($load[0]) > $maxsysload) {
             logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.');
             return;
         }
     }
     // Check for a lockfile.  If it exists, but is over an hour old, it's stale.  Ignore it.
     $lockfile = 'store/[data]/cron';
     if (file_exists($lockfile) && filemtime($lockfile) > time() - 3600 && !get_config('system', 'override_cron_lockfile')) {
         logger("cron: Already running");
         return;
     }
     // Create a lockfile.  Needs two vars, but $x doesn't need to contain anything.
     file_put_contents($lockfile, $x);
     logger('cron: start');
     // run queue delivery process in the background
     Master::Summon(array('Queue'));
     Master::Summon(array('Poller'));
     // maintenance for mod sharedwithme - check for updated items and remove them
     require_once 'include/sharedwithme.php';
     apply_updates();
     // expire any expired mail
     q("delete from mail where expires > '%s' and expires < %s ", dbesc(NULL_DATE), db_utcnow());
     // expire any expired items
     $r = q("select id from item where expires > '2001-01-01 00:00:00' and expires < %s \n\t\t\tand item_deleted = 0 ", db_utcnow());
     if ($r) {
         require_once 'include/items.php';
         foreach ($r as $rr) {
             drop_item($rr['id'], false);
         }
     }
     // delete expired access tokens
     $r = q("select atoken_id from atoken where atoken_expires > '%s' and atoken_expires < %s", dbesc(NULL_DATE), db_utcnow());
     if ($r) {
         require_once 'include/security.php';
         foreach ($r as $rr) {
             atoken_delete($rr['atoken_id']);
         }
     }
     // Ensure that every channel pings a directory server once a month. This way we can discover
     // channels and sites that quietly vanished and prevent the directory from accumulating stale
     // or dead entries.
     $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('30 DAY'));
     if ($r) {
         foreach ($r as $rr) {
             Master::Summon(array('Directory', $rr['channel_id'], 'force'));
             if ($interval) {
                 @time_sleep_until(microtime(true) + (double) $interval);
             }
         }
     }
     // publish any applicable items that were set to be published in the future
     // (time travel posts). Restrict to items that have come of age in the last
     // couple of days to limit the query to something reasonable.
     $r = q("select id from item where item_delayed = 1 and created <= %s  and created > '%s' ", db_utcnow(), dbesc(datetime_convert('UTC', 'UTC', 'now - 2 days')));
     if ($r) {
         foreach ($r as $rr) {
             $x = q("update item set item_delayed = 0 where id = %d", intval($rr['id']));
             if ($x) {
                 $z = q("select * from item where id = %d", intval($message_id));
                 if ($z) {
                     xchan_query($z);
                     $sync_item = fetch_post_tags($z);
                     build_sync_packet($sync_item[0]['uid'], ['item' => [encode_item($sync_item[0], true)]]);
                 }
                 Master::Summon(array('Notifier', 'wall-new', $rr['id']));
             }
         }
     }
     $abandon_days = intval(get_config('system', 'account_abandon_days'));
     if ($abandon_days < 1) {
         $abandon_days = 0;
     }
     // once daily run birthday_updates and then expire in background
     // FIXME: add birthday updates, both locally and for xprof for use
     // by directory servers
     $d1 = intval(get_config('system', 'last_expire_day'));
     $d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd'));
     // Allow somebody to staggger daily activities if they have more than one site on their server,
     // or if it happens at an inconvenient (busy) hour.
     $h1 = intval(get_config('system', 'cron_hour'));
     $h2 = intval(datetime_convert('UTC', 'UTC', 'now', 'G'));
     if ($d2 != $d1 && $h1 == $h2) {
         Master::Summon(array('Cron_daily'));
     }
     // update any photos which didn't get imported properly
     // This should be rare
     $r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = '' \n\t\t\tand xchan_photo_date < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('1 DAY'));
     if ($r) {
         require_once 'include/photo/photo_driver.php';
         foreach ($r as $rr) {
             $photos = import_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash']);
             $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'\n\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($rr['xchan_hash']));
         }
     }
     // pull in some public posts
     if (!get_config('system', 'disable_discover_tab')) {
         Master::Summon(array('Externals'));
     }
     $generation = 0;
     $restart = false;
     if ($argc > 1 && $argv[1] == 'restart') {
         $restart = true;
         $generation = intval($argv[2]);
         if (!$generation) {
             killme();
         }
     }
     reload_plugins();
     $d = datetime_convert();
     // TODO check to see if there are any cronhooks before wasting a process
     if (!$restart) {
         Master::Summon(array('Cronhooks'));
     }
     set_config('system', 'lastcron', datetime_convert());
     //All done - clear the lockfile
     @unlink($lockfile);
     return;
 }
예제 #6
0
 function get()
 {
     $noid = get_config('system', 'disable_openid');
     if ($noid) {
         goaway(z_root());
     }
     logger('mod_openid ' . print_r($_REQUEST, true), LOGGER_DATA);
     if (x($_REQUEST, 'openid_mode')) {
         $openid = new LightOpenID(z_root());
         if ($openid->validate()) {
             logger('openid: validate');
             $authid = normalise_openid($_REQUEST['openid_identity']);
             if (!strlen($authid)) {
                 logger(t('OpenID protocol error. No ID returned.') . EOL);
                 goaway(z_root());
             }
             $x = match_openid($authid);
             if ($x) {
                 $r = q("select * from channel where channel_id = %d limit 1", intval($x));
                 if ($r) {
                     $y = q("select * from account where account_id = %d limit 1", intval($r[0]['channel_account_id']));
                     if ($y) {
                         foreach ($y as $record) {
                             if ($record['account_flags'] == ACCOUNT_OK || $record['account_flags'] == ACCOUNT_UNVERIFIED) {
                                 logger('mod_openid: openid success for ' . $x[0]['channel_name']);
                                 $_SESSION['uid'] = $r[0]['channel_id'];
                                 $_SESSION['account_id'] = $r[0]['channel_account_id'];
                                 $_SESSION['authenticated'] = true;
                                 authenticate_success($record, $r[0], true, true, true, true);
                                 goaway(z_root());
                             }
                         }
                     }
                 }
             }
             // Successful OpenID login - but we can't match it to an existing account.
             // See if they've got an xchan
             $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", dbesc($authid));
             if ($r) {
                 $_SESSION['authenticated'] = 1;
                 $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                 $_SESSION['my_url'] = $r[0]['xchan_url'];
                 $_SESSION['my_address'] = $r[0]['xchan_addr'];
                 $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                 call_hooks('magic_auth_openid_success', $arr);
                 \App::set_observer($r[0]);
                 require_once 'include/security.php';
                 \App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
                 info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                 logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                 if ($_SESSION['return_url']) {
                     goaway($_SESSION['return_url']);
                 }
                 goaway(z_root());
             }
             // no xchan...
             // create one.
             // We should probably probe the openid url and figure out if they have any kind of
             // social presence we might be able to scrape some identifying info from.
             $name = $authid;
             $url = trim($_REQUEST['openid_identity'], '/');
             if (strpos($url, 'http') === false) {
                 $url = 'https://' . $url;
             }
             $pphoto = z_root() . '/' . get_default_profile_photo();
             $parsed = @parse_url($url);
             if ($parsed) {
                 $host = $parsed['host'];
             }
             $attr = $openid->getAttributes();
             if (is_array($attr) && count($attr)) {
                 foreach ($attr as $k => $v) {
                     if ($k === 'namePerson/friendly') {
                         $nick = notags(trim($v));
                     }
                     if ($k === 'namePerson/first') {
                         $first = notags(trim($v));
                     }
                     if ($k === 'namePerson') {
                         $name = notags(trim($v));
                     }
                     if ($k === 'contact/email') {
                         $addr = notags(trim($v));
                     }
                     if ($k === 'media/image/aspect11') {
                         $photosq = trim($v);
                     }
                     if ($k === 'media/image/default') {
                         $photo_other = trim($v);
                     }
                 }
             }
             if (!$nick) {
                 if ($first) {
                     $nick = $first;
                 } else {
                     $nick = $name;
                 }
             }
             require_once 'library/urlify/URLify.php';
             $x = strtolower(\URLify::transliterate($nick));
             if ($nick & $host) {
                 $addr = $nick . '@' . $host;
             }
             $network = 'unknown';
             if ($photosq) {
                 $pphoto = $photosq;
             } elseif ($photo_other) {
                 $pphoto = $photo_other;
             }
             $mimetype = guess_image_type($pphoto);
             $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,\n\t                xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, \n\t\t\t\t\txchan_name_date, xchan_hidden)\n\t                values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ", dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($mimetype), dbesc($pphoto), dbesc($addr), dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($name), dbesc($network), dbesc(datetime_convert()), dbesc(datetime_convert()));
             if ($x) {
                 $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($url));
                 if ($r) {
                     $photos = import_xchan_photo($pphoto, $url);
                     if ($photos) {
                         $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', \n\t\t\t\t\t\t\t\txchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($url));
                     }
                     set_xconfig($url, 'system', 'openid', $authid);
                     $_SESSION['authenticated'] = 1;
                     $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                     $_SESSION['my_url'] = $r[0]['xchan_url'];
                     $_SESSION['my_address'] = $r[0]['xchan_addr'];
                     $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                     call_hooks('magic_auth_openid_success', $arr);
                     \App::set_observer($r[0]);
                     info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                     logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                     if ($_SESSION['return_url']) {
                         goaway($_SESSION['return_url']);
                     }
                     goaway(z_root());
                 }
             }
         }
     }
     notice(t('Login failed.') . EOL);
     goaway(z_root());
     // NOTREACHED
 }
예제 #7
0
function sync_apps($channel, $apps)
{
    if ($channel && $apps) {
        foreach ($apps as $app) {
            $exists = false;
            $term = array_key_exists('term', $app) ? $app['term'] : null;
            $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id']));
            if ($x) {
                $exists = $x[0];
            }
            if (array_key_exists('app_deleted', $app) && $app['app_deleted'] && $app['app_id']) {
                q("delete from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id']));
                if ($exists) {
                    q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($exists['id']));
                }
                continue;
            }
            unset($app['id']);
            unset($app['app_channel']);
            unset($app['term']);
            if ($exists) {
                q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($exists['id']));
            }
            if (!$app['app_created'] || $app['app_created'] === NULL_DATE) {
                $app['app_created'] = datetime_convert();
            }
            if (!$app['app_edited'] || $app['app_edited'] === NULL_DATE) {
                $app['app_edited'] = datetime_convert();
            }
            $app['app_channel'] = $channel['channel_id'];
            if ($app['app_photo']) {
                $x = import_xchan_photo($app['app_photo'], $channel['channel_hash'], true);
                $app['app_photo'] = $x[0];
            }
            if ($exists && $term) {
                foreach ($term as $t) {
                    if (array_key_exists('type', $t)) {
                        $t['ttype'] = $t['type'];
                    }
                    store_item_tag($channel['channel_id'], $exists['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url']));
                }
            }
            if ($exists) {
                if ($exists['app_edited'] >= $app['app_edited']) {
                    continue;
                }
            }
            $hash = $app['app_id'];
            if ($exists) {
                unset($app['app_id']);
                foreach ($app as $k => $v) {
                    $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d", dbesc($k), dbesc($v), dbesc($hash), intval($channel['channel_id']));
                }
            } else {
                dbesc_array($app);
                $r = dbq("INSERT INTO app (`" . implode("`, `", array_keys($app)) . "`) VALUES ('" . implode("', '", array_values($app)) . "')");
                if ($term) {
                    $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($hash), intval($channel['channel_id']));
                    if ($x) {
                        foreach ($term as $t) {
                            if (array_key_exists('type', $t)) {
                                $t['ttype'] = $t['type'];
                            }
                            store_item_tag($channel['channel_id'], $x[0]['id'], TERM_OBJ_APP, $t['ttype'], escape_tags($t['term']), escape_tags($t['url']));
                        }
                    }
                }
            }
        }
    }
}
예제 #8
0
파일: items.php 프로젝트: bashrc/hubzilla
function import_author_unknown($x)
{
    if (!$x['url']) {
        return false;
    }
    $r = q("select xchan_hash from xchan where xchan_network = 'unknown' and xchan_url = '%s' limit 1", dbesc($x['url']));
    if ($r) {
        logger('import_author_unknown: in cache', LOGGER_DEBUG);
        return $r[0]['xchan_hash'];
    }
    $name = trim($x['name']);
    $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_url, xchan_name, xchan_network )\n\t\tvalues ( '%s', '%s', '%s', '%s', '%s' )", dbesc($x['url']), dbesc($x['url']), dbesc($x['url']), dbesc($name ? $name : t('(Unknown)')), dbesc('unknown'));
    if ($r && $x['photo']) {
        $photos = import_xchan_photo($x['photo']['src'], $x['url']);
        if ($photos) {
            /** @bug $arr is undefined in this SQL query */
            $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_url = '%s' and xchan_network = 'unknown'", dbesc(datetime_convert('UTC', 'UTC', $arr['photo_updated'])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($x['url']));
            if ($r) {
                return $x['url'];
            }
        }
    }
    return false;
}
예제 #9
0
파일: import.php 프로젝트: msooon/hubzilla
function sync_apps($channel, $apps)
{
    if ($channel && $apps) {
        foreach ($apps as $app) {
            if (array_key_exists('app_deleted', $app) && $app['app_deleted'] && $app['app_id']) {
                q("delete from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id']));
                continue;
            }
            unset($app['id']);
            unset($app['app_channel']);
            if (!$app['app_created'] || $app['app_created'] === NULL_DATE) {
                $app['app_created'] = datetime_convert();
            }
            if (!$app['app_edited'] || $app['app_edited'] === NULL_DATE) {
                $app['app_edited'] = datetime_convert();
            }
            $app['app_channel'] = $channel['channel_id'];
            if ($app['app_photo']) {
                $x = import_xchan_photo($app['app_photo'], $channel['channel_hash'], true);
                $app['app_photo'] = $x[0];
            }
            $exists = false;
            $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", dbesc($app['app_id']), intval($channel['channel_id']));
            if ($x) {
                if ($x[0]['app_edited'] >= $app['app_edited']) {
                    continue;
                }
                $exists = true;
            }
            $hash = $app['app_id'];
            if ($exists) {
                unset($app['app_id']);
                foreach ($app as $k => $v) {
                    $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d", dbesc($k), dbesc($v), dbesc($hash), intval($channel['channel_id']));
                }
            } else {
                dbesc_array($app);
                $r = dbq("INSERT INTO app (`" . implode("`, `", array_keys($app)) . "`) VALUES ('" . implode("', '", array_values($app)) . "')");
            }
        }
    }
}
예제 #10
0
function discover_by_webbie($webbie)
{
    require_once 'library/HTML5/Parser.php';
    $result = array();
    $network = null;
    $diaspora = false;
    $gnusoc = false;
    $dfrn = false;
    $has_salmon = false;
    $salmon_key = false;
    $atom_feed = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $webbie = strtolower($webbie);
    $x = webfinger_rfc7033($webbie, true);
    if ($x && array_key_exists('links', $x) && $x['links']) {
        foreach ($x['links'] as $link) {
            if (array_key_exists('rel', $link)) {
                // If we discover zot - don't search further; grab the info and get out of
                // here.
                if ($link['rel'] === PROTOCOL_ZOT) {
                    logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
                    if (array_key_exists('zot', $x) && $x['zot']['success']) {
                        $i = import_xchan($x['zot']);
                    } else {
                        $z = z_fetch_url($link['href']);
                        if ($z['success']) {
                            $j = json_decode($z['body'], true);
                            $i = import_xchan($j);
                            return true;
                        }
                    }
                }
                if ($link['rel'] == NAMESPACE_DFRN) {
                    $dfrn = $link['href'];
                }
                if ($link['rel'] == 'magic-public-key') {
                    if (substr($link['href'], 0, 5) === 'data:') {
                        $salmon_key = convert_salmon_key($link['href']);
                    }
                }
                if ($link['rel'] == 'salmon') {
                    $has_salmon = true;
                    $salmon = $link['href'];
                }
                if ($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
                    $atom_feed = $link['href'];
                }
            }
        }
    }
    logger('webfinger: ' . print_r($x, true), LOGGER_DATA, LOG_INFO);
    $arr = array('address' => $webbie, 'success' => false, 'webfinger' => $x);
    call_hooks('discover_channel_webfinger', $arr);
    if ($arr['success']) {
        return true;
    }
    $aliases = array();
    // Now let's make some decisions on what we may need
    // to obtain further info
    $probe_atom = false;
    $probe_old = false;
    $probe_hcard = false;
    $address = '';
    $location = '';
    $nickname = '';
    $fullname = '';
    $avatar = '';
    $pubkey = '';
    if (is_array($x)) {
        if (array_key_exists('address', $x)) {
            $address = $x['address'];
        }
        if (array_key_exists('location', $x)) {
            $location = $x['location'];
        }
        if (array_key_exists('nickname', $x)) {
            $nickname = $x['nickname'];
        }
    }
    if (!$x) {
        $probe_old = true;
    }
    if (!$dfrn && !$has_salmon) {
        $probe_old = true;
    }
    if ($probe_old) {
        $y = old_webfinger($webbie);
        if ($y) {
            logger('old_webfinger: ' . print_r($x, true));
            foreach ($y as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    if (strstr($diaspora_key, 'RSA ')) {
                        $pubkey = rsatopem($diaspora_key);
                    } else {
                        $pubkey = $diaspora_key;
                    }
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] == 'magic-public-key') {
                    if (substr($link['@attributes']['href'], 0, 5) === 'data:') {
                        $salmon_key = convert_salmon_key($link['@attributes']['href']);
                    }
                }
                if ($link['@attributes']['rel'] == 'salmon') {
                    $has_salmon = true;
                    $salmon = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
                    $atom_feed = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] === 'alias') {
                    $aliases[] = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] === 'subject') {
                    $subject = $link['@attributes']['href'];
                }
            }
        }
    }
    if ($subject || $aliases) {
        if (strpos($webbie, '@')) {
            $rhs = substr($webbie, strpos($webbie, '@') + 1);
        } else {
            $m = parse_url($webbie);
            if ($m) {
                $rhs = $m['host'] . ($m['port'] ? ':' . $m['port'] : '');
            }
        }
        $v = array('subject' => $subject, 'aliases' => $aliases);
        $address = find_webfinger_address($v, $rhs);
        $location = find_webfinger_location($v, $rhs);
        if ($address) {
            $nickname = substr($address, 0, strpos($address, '@'));
        }
    }
    if ($salmon_key && $has_salmon && $atom_feed && !$dfrn && !$diaspora) {
        $gnusoc = true;
        $probe_atom = true;
    }
    if (!$pubkey) {
        $pubkey = $salmon_key;
    }
    if (($dfrn || $diaspora) && $hcard) {
        $probe_hcard = true;
    }
    if (!$fullname) {
        $fullname = $nickname;
    }
    if ($probe_atom) {
        $k = z_fetch_url($atom_feed);
        if ($k['success']) {
            $feed_meta = feed_meta($k['body']);
        }
        if ($feed_meta) {
            // stash any discovered pubsubhubbub hubs in case we need to follow them
            // this will save an expensive lookup later
            if ($feed_meta['hubs'] && $address) {
                set_xconfig($address, 'system', 'push_hubs', $feed_meta['hubs']);
                set_xconfig($address, 'system', 'feed_url', $atom_feed);
            }
            if ($feed_meta['author']['author_name']) {
                $fullname = $feed_meta['author']['author_name'];
            }
            if (!$avatar) {
                if ($feed_meta['author']['author_photo']) {
                    $avatar = $feed_meta['author']['author_photo'];
                }
            }
            // for GNU-social over-ride any url aliases we may have picked up in webfinger
            // The author.uri element in the feed is likely to be more accurate
            if ($gnusoc && $feed_meta['author']['author_uri']) {
                $location = $feed_meta['author']['author_uri'];
            }
        }
    } else {
        if ($probe_hcard) {
            $vcard = scrape_vcard($hcard);
            if ($vcard) {
                logger('vcard: ' . print_r($vcard, true), LOGGER_DATA);
                if ($vcard['fn']) {
                    $fullname = $vcard['fn'];
                }
                if ($vcard['photo'] && strpos($vcard['photo'], 'http') !== 0) {
                    $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
                }
                if (!$avatar) {
                    $avatar = $vcard['photo'];
                }
            }
        }
    }
    if ($profile && !$location) {
        $location = $profile;
    }
    if ($location) {
        $m = parse_url($location);
        $base = $m['scheme'] . '://' . $m['host'];
        $host = $m['host'];
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($dfrn) {
            $network = 'friendica-over-diaspora';
        } else {
            $network = 'diaspora';
        }
        $base = trim($diaspora_base, '/');
        $notify = $base . '/receive';
    } else {
        if ($gnusoc) {
            $network = 'gnusoc';
            $notify = $salmon;
        }
    }
    logger('network: ' . $network);
    logger('address: ' . $address);
    logger('fullname: ' . $fullname);
    logger('pubkey: ' . $pubkey);
    logger('location: ' . $location);
    // if we have everything we need, let's create the records
    if ($network && $address && $fullname && $pubkey && $location) {
        $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($address));
        if ($r) {
            $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1", dbesc($fullname), dbesc($network), dbesc(datetime_convert()), dbesc($address));
        } else {
            $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($address), dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($pubkey), dbesc($address), dbesc($location), dbesc($fullname), dbesc($network), dbescdate(datetime_convert()));
        }
        $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($address));
        if (!$r) {
            $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)", dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($address), dbesc($address), dbesc($network), dbesc($base), dbesc($host), dbesc($notify), dbescdate(datetime_convert()));
        }
        $photos = import_xchan_photo($avatar, $address);
        $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbescdate(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($address));
        return true;
    }
    return false;
}
예제 #11
0
function diaspora_profile($importer, $xml, $msg)
{
    $a = get_app();
    $diaspora_handle = notags(diaspora_get_author($xml));
    logger('xml: ' . print_r($xml, true), LOGGER_DEBUG);
    if ($diaspora_handle != $msg['author']) {
        logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
        return 202;
    }
    $contact = diaspora_get_contact_by_handle($importer['channel_id'], $diaspora_handle);
    if (!$contact) {
        return;
    }
    if ($contact['blocked']) {
        logger('diaspora_profile: Ignoring this author.');
        return 202;
    }
    $name = unxmlify($xml['first_name'] . ($xml['last_name'] ? ' ' . $xml['last_name'] : ''));
    $image_url = unxmlify($xml['image_url']);
    $birthday = unxmlify($xml['birthday']);
    $handle_parts = explode("@", $diaspora_handle);
    if ($name === '') {
        $name = $handle_parts[0];
    }
    if (preg_match("|^https?://|", $image_url) === 0) {
        $image_url = "http://" . $handle_parts[1] . $image_url;
    }
    require_once 'include/photo/photo_driver.php';
    $images = import_xchan_photo($image_url, $contact['xchan_hash']);
    // Generic birthday. We don't know the timezone. The year is irrelevant.
    $birthday = str_replace('1000', '1901', $birthday);
    $birthday = datetime_convert('UTC', 'UTC', $birthday, 'Y-m-d');
    // this is to prevent multiple birthday notifications in a single year
    // if we already have a stored birthday and the 'm-d' part hasn't changed, preserve the entry, which will preserve the notify year
    if (substr($birthday, 5) === substr($contact['bd'], 5)) {
        $birthday = $contact['bd'];
    }
    $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' ", dbesc($name), dbesc(datetime_convert()), dbesc($images[0]), dbesc($images[1]), dbesc($images[2]), dbesc($images[3]), dbesc(datetime_convert()), intval($contact['xchan_hash']));
    return;
}
예제 #12
0
파일: Apps.php 프로젝트: BlaBlaNet/hubzilla
 public static function app_update($arr)
 {
     $darray = array();
     $ret = array('success' => false);
     $darray['app_url'] = x($arr, 'url') ? $arr['url'] : '';
     $darray['app_channel'] = x($arr, 'uid') ? $arr['uid'] : 0;
     $darray['app_id'] = x($arr, 'guid') ? $arr['guid'] : 0;
     if (!$darray['app_url'] || !$darray['app_channel'] || !$darray['app_id']) {
         return $ret;
     }
     if ($arr['photo'] && !strstr($arr['photo'], z_root())) {
         $x = import_xchan_photo($arr['photo'], get_observer_hash(), true);
         $arr['photo'] = $x[1];
     }
     $darray['app_sig'] = x($arr, 'sig') ? $arr['sig'] : '';
     $darray['app_author'] = x($arr, 'author') ? $arr['author'] : get_observer_hash();
     $darray['app_name'] = x($arr, 'name') ? escape_tags($arr['name']) : t('Unknown');
     $darray['app_desc'] = x($arr, 'desc') ? escape_tags($arr['desc']) : '';
     $darray['app_photo'] = x($arr, 'photo') ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80);
     $darray['app_version'] = x($arr, 'version') ? escape_tags($arr['version']) : '';
     $darray['app_addr'] = x($arr, 'addr') ? escape_tags($arr['addr']) : '';
     $darray['app_price'] = x($arr, 'price') ? escape_tags($arr['price']) : '';
     $darray['app_page'] = x($arr, 'page') ? escape_tags($arr['page']) : '';
     $darray['app_requires'] = x($arr, 'requires') ? escape_tags($arr['requires']) : '';
     $darray['app_system'] = x($arr, 'system') ? intval($arr['system']) : 0;
     $darray['app_deleted'] = x($arr, 'deleted') ? intval($arr['deleted']) : 0;
     $edited = datetime_convert();
     $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), dbesc($darray['app_desc']), dbesc($darray['app_url']), dbesc($darray['app_photo']), dbesc($darray['app_version']), dbesc($darray['app_addr']), dbesc($darray['app_price']), dbesc($darray['app_page']), dbesc($darray['app_requires']), dbesc($edited), intval($darray['app_system']), intval($darray['app_deleted']), dbesc($darray['app_id']), intval($darray['app_channel']));
     if ($r) {
         $ret['success'] = true;
         $ret['app_id'] = $darray['app_id'];
     }
     $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", dbesc($darray['app_id']), intval($darray['app_channel']));
     if ($x) {
         q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($x[0]['id']));
         if ($arr['categories']) {
             $y = explode(',', $arr['categories']);
             if ($y) {
                 foreach ($y as $t) {
                     $t = trim($t);
                     if ($t) {
                         store_item_tag($darray['app_channel'], $x[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, escape_tags($t), escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
                     }
                 }
             }
         }
     }
     return $ret;
 }
예제 #13
0
function xchan_store($arr)
{
    logger('xchan_store: ' . print_r($arr, true));
    if (!$arr['hash']) {
        $arr['hash'] = $arr['guid'];
    }
    if (!$arr['hash']) {
        return false;
    }
    $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($arr['hash']));
    if ($r) {
        return true;
    }
    if (!$arr['network']) {
        $arr['network'] = 'unknown';
    }
    if (!$arr['name']) {
        $arr['name'] = 'unknown';
    }
    if (!$arr['url']) {
        $arr['url'] = z_root();
    }
    if (!$arr['photo']) {
        $arr['photo'] = z_root() . '/' . get_default_profile_photo();
    }
    $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_instance_url, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s','%s',%d, %d, %d, %d, %d, %d, %d, '%s') ", dbesc($arr['hash']), dbesc($arr['guid']), dbesc($arr['guid_sig']), dbesc($arr['pubkey']), dbesc($arr['address']), dbesc($arr['url']), dbesc($arr['connurl']), dbesc($arr['follow']), dbesc($arr['connpage']), dbesc($arr['name']), dbesc($arr['network']), dbesc($arr['instance_url']), intval($arr['hidden']), intval($arr['orphan']), intval($arr['censored']), intval($arr['selfcensored']), intval($arr['system']), intval($arr['pubforum']), intval($arr['deleted']), dbesc(datetime_convert()));
    if (!$r) {
        return $r;
    }
    $photos = import_xchan_photo($arr['photo'], $arr['hash']);
    $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($arr['hash']));
    return $r;
}
예제 #14
0
파일: apps.php 프로젝트: TamirAl/hubzilla
function app_update($arr)
{
    $darray = array();
    $ret = array('success' => false);
    $darray['app_url'] = x($arr, 'url') ? $arr['url'] : '';
    $darray['app_channel'] = x($arr, 'uid') ? $arr['uid'] : 0;
    $darray['app_id'] = x($arr, 'guid') ? $arr['guid'] : 0;
    if (!$darray['app_url'] || !$darray['app_channel'] || !$darray['app_id']) {
        return $ret;
    }
    if ($arr['photo'] && !strstr($arr['photo'], z_root())) {
        $x = import_xchan_photo($arr['photo'], get_observer_hash(), true);
        $arr['photo'] = $x[1];
    }
    $darray['app_sig'] = x($arr, 'sig') ? $arr['sig'] : '';
    $darray['app_author'] = x($arr, 'author') ? $arr['author'] : get_observer_hash();
    $darray['app_name'] = x($arr, 'name') ? escape_tags($arr['name']) : t('Unknown');
    $darray['app_desc'] = x($arr, 'desc') ? escape_tags($arr['desc']) : '';
    $darray['app_photo'] = x($arr, 'photo') ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80);
    $darray['app_version'] = x($arr, 'version') ? escape_tags($arr['version']) : '';
    $darray['app_addr'] = x($arr, 'addr') ? escape_tags($arr['addr']) : '';
    $darray['app_price'] = x($arr, 'price') ? escape_tags($arr['price']) : '';
    $darray['app_page'] = x($arr, 'page') ? escape_tags($arr['page']) : '';
    $darray['app_requires'] = x($arr, 'requires') ? escape_tags($arr['requires']) : '';
    $edited = datetime_convert();
    $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s' where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), dbesc($darray['app_desc']), dbesc($darray['app_url']), dbesc($darray['app_photo']), dbesc($darray['app_version']), dbesc($darray['app_addr']), dbesc($darray['app_price']), dbesc($darray['app_page']), dbesc($darray['app_requires']), dbesc($edited), dbesc($darray['app_id']), intval($darray['app_channel']));
    if ($r) {
        $ret['success'] = true;
        $ret['app_id'] = $darray['app_id'];
    }
    return $ret;
}
예제 #15
0
파일: poller.php 프로젝트: msooon/hubzilla
function poller_run($argv, $argc)
{
    cli_startup();
    $a = get_app();
    $maxsysload = intval(get_config('system', 'maxloadavg'));
    if ($maxsysload < 1) {
        $maxsysload = 50;
    }
    if (function_exists('sys_getloadavg')) {
        $load = sys_getloadavg();
        if (intval($load[0]) > $maxsysload) {
            logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
            return;
        }
    }
    $interval = intval(get_config('system', 'poll_interval'));
    if (!$interval) {
        $interval = get_config('system', 'delivery_interval') === false ? 3 : intval(get_config('system', 'delivery_interval'));
    }
    // Check for a lockfile.  If it exists, but is over an hour old, it's stale.  Ignore it.
    $lockfile = 'store/[data]/poller';
    if (file_exists($lockfile) && filemtime($lockfile) > time() - 3600 && !get_config('system', 'override_poll_lockfile')) {
        logger("poller: Already running");
        return;
    }
    // Create a lockfile.  Needs two vars, but $x doesn't need to contain anything.
    file_put_contents($lockfile, $x);
    logger('poller: start');
    // run queue delivery process in the background
    proc_run('php', "include/queue.php");
    // maintenance for mod sharedwithme - check for updated items and remove them
    require_once 'include/sharedwithme.php';
    apply_updates();
    // expire any expired mail
    q("delete from mail where expires != '%s' and expires < %s ", dbesc(NULL_DATE), db_utcnow());
    // expire any expired items
    $r = q("select id from item where expires != '%s' and expires < %s \n\t\tand item_deleted = 0 ", dbesc(NULL_DATE), db_utcnow());
    if ($r) {
        require_once 'include/items.php';
        foreach ($r as $rr) {
            drop_item($rr['id'], false);
        }
    }
    // Ensure that every channel pings a directory server once a month. This way we can discover
    // channels and sites that quietly vanished and prevent the directory from accumulating stale
    // or dead entries.
    $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('30 DAY'));
    if ($r) {
        foreach ($r as $rr) {
            proc_run('php', 'include/directory.php', $rr['channel_id'], 'force');
            if ($interval) {
                @time_sleep_until(microtime(true) + (double) $interval);
            }
        }
    }
    // publish any applicable items that were set to be published in the future
    // (time travel posts). Restrict to items that have come of age in the last
    // couple of days to limit the query to something reasonable.
    $r = q("select id from item where item_delayed = 1 and created <= %s  and created > '%s' ", db_utcnow(), dbesc(datetime_convert('UTC', 'UTC', 'now - 2 days')));
    if ($r) {
        foreach ($r as $rr) {
            $x = q("update item set item_delayed = 0 where id = %d", intval($rr['id']));
            if ($x) {
                proc_run('php', 'include/notifier.php', 'wall-new', $rr['id']);
            }
        }
    }
    $abandon_days = intval(get_config('system', 'account_abandon_days'));
    if ($abandon_days < 1) {
        $abandon_days = 0;
    }
    // once daily run birthday_updates and then expire in background
    // FIXME: add birthday updates, both locally and for xprof for use
    // by directory servers
    $d1 = intval(get_config('system', 'last_expire_day'));
    $d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd'));
    // Allow somebody to staggger daily activities if they have more than one site on their server,
    // or if it happens at an inconvenient (busy) hour.
    $h1 = intval(get_config('system', 'cron_hour'));
    $h2 = intval(datetime_convert('UTC', 'UTC', 'now', 'G'));
    $dirmode = get_config('system', 'directory_mode');
    /**
     * Cron Daily
     *
     * Actions in the following block are executed once per day, not on every poller run
     *
     */
    if ($d2 != $d1 && $h1 == $h2) {
        require_once 'include/dir_fns.php';
        check_upstream_directory();
        call_hooks('cron_daily', datetime_convert());
        $d3 = intval(datetime_convert('UTC', 'UTC', 'now', 'N'));
        if ($d3 == 7) {
            /**
             * Cron Weekly
             * 
             * Actions in the following block are executed once per day only on Sunday (once per week).
             *
             */
            call_hooks('cron_weekly', datetime_convert());
            z_check_cert();
            require_once 'include/hubloc.php';
            prune_hub_reinstalls();
            require_once 'include/Contact.php';
            mark_orphan_hubsxchans();
            // get rid of really old poco records
            q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ", db_utcnow(), db_quoteinterval('14 DAY'));
            $dirmode = intval(get_config('system', 'directory_mode'));
            if ($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
                logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())), true));
            }
            // Check for dead sites
            proc_run('php', 'include/checksites.php');
            // update searchable doc indexes
            proc_run('php', 'include/importdoc.php');
            /**
             * End Cron Weekly
             */
        }
        update_birthdays();
        //update statistics in config
        require_once 'include/statistics_fns.php';
        update_channels_total_stat();
        update_channels_active_halfyear_stat();
        update_channels_active_monthly_stat();
        update_local_posts_stat();
        // expire any read notifications over a month old
        q("delete from notify where seen = 1 and date < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('30 DAY'));
        // expire old delivery reports
        $keep_reports = intval(get_config('system', 'expire_delivery_reports'));
        if ($keep_reports === 0) {
            $keep_reports = 30;
        }
        q("delete from dreport where dreport_time < %s - INTERVAL %s", db_utcnow(), db_quoteinterval($keep_reports . ' DAY'));
        // expire any expired accounts
        downgrade_accounts();
        // If this is a directory server, request a sync with an upstream
        // directory at least once a day, up to once every poll interval.
        // Pull remote changes and push local changes.
        // potential issue: how do we keep from creating an endless update loop?
        if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
            require_once 'include/dir_fns.php';
            sync_directories($dirmode);
        }
        set_config('system', 'last_expire_day', $d2);
        proc_run('php', 'include/expire.php');
        proc_run('php', 'include/cli_suggest.php');
        require_once 'include/hubloc.php';
        remove_obsolete_hublocs();
        /**
         * End Cron Daily
         */
    }
    // update any photos which didn't get imported properly
    // This should be rare
    $r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = '' \n\t\tand xchan_photo_date < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('1 DAY'));
    if ($r) {
        require_once 'include/photo/photo_driver.php';
        foreach ($r as $rr) {
            $photos = import_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash']);
            $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'\n\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($rr['xchan_hash']));
        }
    }
    // pull in some public posts
    if (!get_config('system', 'disable_discover_tab')) {
        proc_run('php', 'include/externals.php');
    }
    $manual_id = 0;
    $generation = 0;
    $force = false;
    $restart = false;
    if ($argc > 1 && $argv[1] == 'force') {
        $force = true;
    }
    if ($argc > 1 && $argv[1] == 'restart') {
        $restart = true;
        $generation = intval($argv[2]);
        if (!$generation) {
            killme();
        }
    }
    if ($argc > 1 && intval($argv[1])) {
        $manual_id = intval($argv[1]);
        $force = true;
    }
    $sql_extra = $manual_id ? " AND abook_id = " . intval($manual_id) . " " : "";
    reload_plugins();
    $d = datetime_convert();
    // TODO check to see if there are any cronhooks before wasting a process
    if (!$restart) {
        proc_run('php', 'include/cronhooks.php');
    }
    // Only poll from those with suitable relationships
    $abandon_sql = $abandon_days ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days) . ' DAY')) : '';
    $randfunc = db_getfunc('RAND');
    $contacts = q("SELECT * FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash \n\t\tLEFT JOIN account on abook_account = account_id\n\t\twhere abook_self = 0\n\t\t{$sql_extra} \n\t\tAND (( account_flags = %d ) OR ( account_flags = %d )) {$abandon_sql} ORDER BY {$randfunc}", intval(ACCOUNT_OK), intval(ACCOUNT_UNVERIFIED));
    if ($contacts) {
        foreach ($contacts as $contact) {
            $update = false;
            $t = $contact['abook_updated'];
            $c = $contact['abook_connected'];
            if (intval($contact['abook_feed'])) {
                $min = service_class_fetch($contact['abook_channel'], 'minimum_feedcheck_minutes');
                if (!$min) {
                    $min = intval(get_config('system', 'minimum_feedcheck_minutes'));
                }
                if (!$min) {
                    $min = 60;
                }
                $x = datetime_convert('UTC', 'UTC', "now - {$min} minutes");
                if ($c < $x) {
                    proc_run('php', 'include/onepoll.php', $contact['abook_id']);
                    if ($interval) {
                        @time_sleep_until(microtime(true) + (double) $interval);
                    }
                }
                continue;
            }
            if ($contact['xchan_network'] !== 'zot') {
                continue;
            }
            if ($c == $t) {
                if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) {
                    $update = true;
                }
            } else {
                // if we've never connected with them, start the mark for death countdown from now
                if ($c == NULL_DATE) {
                    $r = q("update abook set abook_connected = '%s'  where abook_id = %d", dbesc(datetime_convert()), intval($contact['abook_id']));
                    $c = datetime_convert();
                    $update = true;
                }
                // He's dead, Jim
                if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 30 day")) > 0) {
                    $r = q("update abook set abook_archived = 1 where abook_id = %d", intval($contact['abook_id']));
                    $update = false;
                    continue;
                }
                if (intval($contact['abook_archived'])) {
                    $update = false;
                    continue;
                }
                // might be dead, so maybe don't poll quite so often
                // recently deceased, so keep up the regular schedule for 3 days
                if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 3 day")) > 0 && strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 1 day")) > 0) {
                    $update = true;
                }
                // After that back off and put them on a morphine drip
                if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 2 day")) > 0) {
                    $update = true;
                }
            }
            if (intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) {
                continue;
            }
            if (!$update && !$force) {
                continue;
            }
            proc_run('php', 'include/onepoll.php', $contact['abook_id']);
            if ($interval) {
                @time_sleep_until(microtime(true) + (double) $interval);
            }
        }
    }
    if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
        $r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last = '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ", intval(UPDATE_FLAGS_UPDATED), dbesc(NULL_DATE), db_utcnow(), db_quoteinterval('7 DAY'));
        if ($r) {
            foreach ($r as $rr) {
                // If they didn't respond when we attempted before, back off to once a day
                // After 7 days we won't bother anymore
                if ($rr['ud_last'] != NULL_DATE) {
                    if ($rr['ud_last'] > datetime_convert('UTC', 'UTC', 'now - 1 day')) {
                        continue;
                    }
                }
                proc_run('php', 'include/onedirsync.php', $rr['ud_id']);
                if ($interval) {
                    @time_sleep_until(microtime(true) + (double) $interval);
                }
            }
        }
    }
    set_config('system', 'lastpoll', datetime_convert());
    //All done - clear the lockfile
    @unlink($lockfile);
    return;
}