Created
October 31, 2013 21:44
-
-
Save philfreo/7257723 to your computer and use it in GitHub Desktop.
Facebook Perl source code from 2005. When browsing around thefacebook.com in 2005 the server spit out some server-side source code rather than running it. I believe this was for their old graph feature that let you visualize the graph between all your friends. The filename is `mygraph.svgz` and contains some gems such as a commented out "zuck" d…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use Mysql; | |
use strict; | |
use vars qw($school_name); | |
use vars qw($pass); | |
require "./cgi-lib.pl"; | |
#do "./school_name.pl"; | |
do "../password.pl"; | |
my (%input, $text, $field); | |
&ReadParse(\%input); | |
my @rawCookies = split (/; /,$ENV{'HTTP_COOKIE'}); | |
my %cookies; | |
foreach(@rawCookies){ | |
my ($key, $val) = split (/=/,$_); | |
$cookies{$key} = $val; | |
} | |
my $id = $input{id}; | |
my $user = $input{user}; | |
my $code = $input{code}; | |
my $course = 0;#$input{course}; | |
my @node; | |
my @edge; | |
#my $db_data = Mysql->connect("69.28.179.12", "login", "mark", $pass); | |
my $db_data = Mysql->connect("$cookies{host}", "$cookies{db}", "mark", $pass); | |
my $map; | |
if ($ENV{'HTTP_HOST'} =~ m/^(.*)\.thefacebook\.com/) { | |
$map = $1; | |
} | |
my $cookie_host = $cookies{host}; | |
my $cookie_db = $cookies{db}; | |
my $sql = "SELECT * FROM school_data where map='$map'"; | |
my $retval = $db_data->query($sql); | |
my %rs = $retval->fetchhash(); | |
my $host = $rs{ip}; | |
my $dbname = $rs{db}; | |
#my $sql = "INSERT INTO viz (user,map,host,db) VALUES ('$user', '$map','$host', '$dbname')"; | |
#$db_data->query($sql); | |
my $db = Mysql->connect($host, $dbname, "mark", $pass); | |
#my $db = Mysql->connect("69.28.179.11", "facebook", "mark", $pass); | |
my $retval; my $sql; | |
my %privacy; | |
my $num_degrees = 1; | |
my @already_expanded; | |
my %cs; | |
sub morph { | |
my ($number) = @_; | |
return ((((($number % 7) * 13) % 17) * 19) % 23); | |
} | |
sub share_course { | |
my ($user1, $user2) = @_; | |
$sql = "SELECT count(*) as count FROM course as course1, course as course2 WHERE " . | |
"course1.id = '$user1' AND course2.id = '$user2' AND course1.course_id = course2.course_id"; | |
$retval = $db->query($sql); | |
my %rs = $retval->fetchhash(); | |
return $rs{count}; | |
} | |
sub is_one_degree { | |
my ($user1, $user2) = @_; | |
$sql = "SELECT count(*) as count FROM friend WHERE user1 = '$user1' AND user2 = '$user2'"; | |
$retval = $db->query($sql); | |
my %rs = $retval->fetchhash(); | |
return $rs{count}; | |
} | |
sub is_two_degrees { | |
#my ($user1, $user2) = @_; | |
#$sql = "SELECT count(*) as count FROM friend as f1, friend as f2 " . | |
# "WHERE f1.user1 = '$user1' AND f1.user2 = f2.user1 AND f2.user2 = '$user2'"; | |
#my %rs = $retval->fetchhash(); | |
#return $rs{count}; | |
return 0; | |
} | |
sub is_three_degrees { | |
#my ($user1, $user2) = @_; | |
return 0; | |
} | |
sub can_see { | |
my ($user, $id, $type) = @_; | |
if ($user eq $id) { return 1; } | |
$sql = "SELECT house, year, " . $type . "_domain, " . $type . "_type, " . | |
$type . "_allow FROM info WHERE info.id = '$id'"; | |
$retval = $db->query($sql); | |
my %control = $retval->fetchhash(); | |
my $allow = $control{$type . '_allow'}; | |
my $domain = $control{$type . '_domain'}; | |
my $privacy_type = $privacy{$type}; | |
if (($domain eq "" or ($privacy{email} =~ m/$domain$/)) and | |
($control{$type . '_type'} =~ m/-$privacy_type/)) { | |
if ($allow =~ m/-1/) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-2/) and $privacy{year} eq $control{year}) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-3/) and $privacy{house} eq $control{house}) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-4/) and share_course($user, $id)) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-5/) and is_one_degree($user, $id)) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-6/) and is_two_degrees($user, $id)) { | |
$cs{$id} = 1; | |
return 1; | |
} elsif (($allow =~ m/-7/) and is_three_degrees($user, $id)) { | |
$cs{$id} = 1; | |
return 1; | |
} | |
} | |
return 0; | |
} | |
sub find_node { | |
my ($id, $type) = @_; | |
for (my $i = 0; $i < @node; $i++) { | |
if ($node[$i]{id} eq $id and $node[$i]{type} eq $type) { | |
return $i; | |
} | |
} | |
return -1; | |
} | |
sub find_connections { | |
my ($this, $degree, $is_course) = @_; | |
my ($type, $type_id); | |
if (!$is_course) { | |
$already_expanded[@already_expanded] = $this; | |
$sql = "SELECT * FROM friend WHERE user1 = '$this' LIMIT 0, 200"; | |
$type = "friend"; | |
$type_id = 1; | |
} else { | |
$sql = "SELECT * FROM course WHERE course_id = '$this'"; | |
$type = "course"; | |
$type_id = 0; | |
} | |
my $return = $db->query($sql); | |
while (my %row = $return->fetchhash()) { | |
my $new_id; | |
if (!$is_course) { | |
# get the new id from the friend pair | |
#if ($row{user1} eq $this) { | |
# $new_id = $row{user2}; | |
#} else { | |
# $new_id = $row{user1}; | |
#} | |
$new_id = $row{user2}; | |
} else { | |
$new_id = $row{id}; | |
} | |
if ($degree > $num_degrees or $cs{$new_id} or can_see($user, $new_id, $type)) { | |
# see if the id is already a node; if not, add it | |
my $node_exists = 0; | |
for (my $i = 0; $i < @node and !$node_exists; $i++) { | |
if ($node[$i]{id} eq $new_id and $node[$i]{type} eq 1) { | |
$node_exists = 1; | |
} | |
} | |
if (!$node_exists and $degree <= $num_degrees) { | |
my $next_node = @node; | |
$node[$next_node]{id} = $new_id; | |
$node[$next_node]{type} = 1; | |
} | |
# see if there's an edge between the two already; if not, add it | |
if ($node_exists or $degree <= $num_degrees) { | |
my $edge_exists = 0; | |
my $this_index = find_node ($this, $type_id); | |
my $new_index = find_node ($new_id, 1); | |
for (my $i = 0; $i < @edge and !$edge_exists; $i++) { | |
if (($edge[$i][0] eq $this_index and $edge[$i][1] eq $new_index) or | |
($edge[$i][0] eq $new_index and $edge[$i][1] eq $this_index)) { | |
$edge_exists = 1; | |
} | |
} | |
if (!$edge_exists) { | |
my $next_edge = @edge; | |
$edge[$next_edge][0] = $this_index; | |
$edge[$next_edge][1] = $new_index; | |
} | |
} | |
# if we want to consider friends farther out, do so now | |
if ($degree < $num_degrees + 1) { | |
my $expansion_exists = 0; | |
for (my $i = 0; $i < @already_expanded and !$expansion_exists; $i++) { | |
if ($already_expanded[$i] eq $new_id) { | |
$expansion_exists = 1; | |
} | |
} | |
if (!$expansion_exists) { | |
if (!$is_course or can_see ($user, $new_id, "friend")) { | |
find_connections ($new_id, $degree + 1, 0); | |
} | |
} | |
} | |
} | |
} | |
} | |
sub identify_nodes { | |
for (my $i = 0; $i < @node; $i++) { | |
if ($node[$i]{type}) { | |
$sql = "SELECT name FROM info WHERE id = '" . $node[$i]{id} . "'"; | |
} else { | |
$sql = "SELECT name FROM course_list WHERE id = '" . $node[$i]{id} . "'"; | |
} | |
$retval = $db->query($sql); | |
my %row = $retval->fetchhash(); | |
$node[$i]{name} = $row{name}; | |
} | |
} | |
if ($code == &morph($user) and &can_see($user, $id, "friend")) { | |
# figure out what's going into the graph | |
$sql = "SELECT email, house, year FROM info WHERE info.id = '$user'"; | |
$retval = $db->query($sql); | |
%privacy = $retval->fetchhash(); | |
$node[0]{id} = $id; | |
if ($course) { | |
$node[0]{type} = 0; | |
} else { | |
$node[0]{type} = 1; | |
} | |
find_connections ($id, 1, $course); | |
identify_nodes (); | |
# generate the graph file | |
my $o; | |
my $outfile = "/tmp/thefacebook-$id-graph-" . time(); | |
open $o, "> $outfile"; | |
# headers | |
print $o "graph g {\n"; | |
print $o "start=\"yes\"\n"; | |
print $o "size=\"20,20\"\n"; | |
print $o "page=\"20,20\"\n"; | |
print $o "maxiter=1000\n"; | |
print $o "resolution=100\n"; | |
print $o "center=true\n"; | |
print $o "bgcolor=white\n"; | |
print $o "title=\"A Graph\"\n"; | |
# nodes | |
print $o "node [shape=box,fontname=\"Tahoma\",style=filled]\n"; | |
for (my $i = 0; $i < @node; $i++) { | |
my $name = $node[$i]{name}; | |
$name =~ s/[^A-Z0-9'. ]//gi; | |
my ($red, $green, $blue); | |
do { | |
$red = int(rand() * 201); | |
$green = int(rand() * 201); | |
$blue = int(rand() * 56) + 200; | |
} while ($red + $green + $blue < 400); | |
my $extra = ""; | |
if ($i eq 0) { | |
$extra = ",fontsize=32,label=\"$name\""; | |
} else { | |
$extra = ",fontsize=24,label=\"$name\""; | |
} | |
printf $o "n$i [color=\"#%02x%02x%02x\"$extra]\n", $red, $green, $blue; | |
} | |
# edges | |
print $o "edge [len=8,color=\"#555555\"]\n"; | |
for (my $i = 0; $i < @edge; $i++) { | |
my $name1 = $node[$edge[$i][0]]{name}; | |
my $name2 = $node[$edge[$i][1]]{name}; | |
print $o "n$edge[$i][0] -- n$edge[$i][1] [dir=both,weight=1]\n"; | |
#print $o "$name1 -- $name2 [dir=both,weight=1]\n"; | |
} | |
# footer | |
print $o "}\n\n"; | |
# compile the graph and output | |
my $cmd = "nice neato -Tsvgz $outfile|"; | |
print "Content-Encoding: gzip\n"; | |
print "Content-Type: image/svg+xml\n\n"; | |
#print "Content-Type: text/html\n\n"; | |
my $file; | |
my $pid = open ($file, $cmd); | |
while (my $line = <$file>) { | |
print $line; | |
} | |
close $o; | |
unlink $outfile; | |
#print "what is up..\n"; | |
} else { | |
print &PrintHeader; | |
print "Authentication failed. Return <a href='http://"; | |
print $school_name; | |
print ".thefacebook.com/home.php'>home</a>.\n"; | |
} | |
#print "end...\n"; | |
Was this written by Mark Z.?
Едва ли Марк писал. К тому времени на него уже команда программистов работала. Так что кто-то из них сиё написал.
since we have both this and 2007 versions of facebooks source code, im waiting for the og friendster or myspace source code to get leaked
Was this written by Mark Z.?
yees
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://www.perl.org/