Tech Guru Guide Bookazine 03 (Sampler)

Page 1

em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta hile True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curse screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clea r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 5000 em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rai ew todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } els rmat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_task iority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past error TGG03 2015 dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygam splay.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(sta

Fully revised & updated EDITion

power up your linux skills • the kernel • networks • servers • hardware 180 pages of tutoRials Master New skills you can apply to any project


Get the UK’s best-selling

Linux magazine

OUT NOW!

DELIVERED DIRECT TO YOUR DOOR Order online at www.myfavouritemagazines.co.uk or find us in your nearest supermarket, newsagent or bookstore!


gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rail new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else ormat.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep) use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv ehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_ he_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame nit() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1 while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rail -version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice ...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rail generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_ past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639) andrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/per $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen >addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem instal bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html edirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random impor andrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0 #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80) $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task] ormat.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impor pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ange(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; i $star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :tes do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { rende son: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exe ake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock( tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0 $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” ormat.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_a < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) fo event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-uni espond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exe ake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) i due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)


Editorial team Managing Art Editor

Editor

Contributors

Fraser McDermott

Neil Mohr

additional art

Editor-in-chief

Elly Walton

Graham Barlow

Jonni Bidwell, Matt Beilby, Neil Bothwick, Chris Brown, Jolyon Brown, Kent Elchuk, Matthew Hanson, Les Pounder, Richard Smedley, Alexander Tolstoy, Mihalis Tsoukalos.

Management

Marketing

Circulation

content & marketing director

Marketing Manager

Trade Marketing Manager

Nial Ferguson

Richard Stephens

Juliette Winyard Phone +44(0)7551 150984

Head of Content & marketing, tech

Nick Merritt

Print & production

Licensing

group editor-in-chief

PRODUCTION Manager

Licensing & Syndication Director

Paul Newman

Mark Constance

Group art director

Production Controller

Steve Gotobed

Marie Quilter

Regina Erak regina.erak@futurenet.com Phone +44(0)1225 442244 Fax +44 (0)1225 732275

Subscriptions UK reader order line & enquiries: 0844 848 2852 Overseas reader order line & enquiries: +44 (0)1604 251045 Online enquiries: www.myfavouritemagazines.co.uk

Future Publishing Limited Quay House, The Ambury, Bath, BA1 1UA, UK www.futureplc.com www.myfavouritemagazines.co.uk Phone +44 ( 0 )1225 442244 Fax +44 ( 0 )1225 732275 All contents copyright © 2015 Future Publishing Limited or published under licence. All  rights reserved. No part of this magazine may be reproduced, stored, transmitted or  used in any way without the prior written permission of the publisher. Future Publishing Limited (company number 2008885) is registered in England and Wales. Registered office: Registered office: Quay House, The Ambury, Bath, BA1 1UA. All information contained in this publication is for information only and is, as far as we are aware, correct at the time of going to press. Future cannot accept any responsibility for errors or inaccuracies in such information. You are advised to contact manufacturers and retailers directly with regard to the price and other details of products or services referred to in this publication. Apps and websites mentioned in this publication are not under our control. We are not responsible for their contents or any changes or updates to them. If you submit unsolicited material to us, you automatically grant Future a licence to publish your submission in whole or in part in all editions of the magazine, including licensed editions worldwide and in any physical or digital format throughout the world. Any material you submit is sent at your risk and, although every care is taken, neither Future nor its employees, agents or subcontractors shall be liable for loss or damage. Future is an award-winning international media group and leading digital business. We reach more than 49 million international consumers a month and create world-class content and advertising solutions for passionate consumers online, on tablet & smartphone and in print. Future plc is a public company quoted on the London Stock Exchange (symbol: FUTR). www.futureplc.com

Chief executive Zillah Byng-Maddick Non-executive chairman Peter Allen Chief financial officer Richard Haley Tel +44 (0)207 042 4000 (London) Tel +44 (0)1225 442 244 (Bath)


…to the super-enhanced Hacker’s Manual for 2015. Dive in and learn how to hack everything. Hacker! Lock up the children and hide the silver! Hacking has a bad name in the mainstream press, but we know the truth, hacking has much nobler roots. It’s generally held as originating at MIT, in the 1960s, as a term for the crème de la crème of programmers. They were the master alchemists of languages such as Fortran, and known for pushing them beyond their limitations and making them work in ways they were never intended – what they achieved often felt like magic. Hacking is really about making the most of

your systems, turning the conventional into the unconventional, and subverting tools to tasks no one thought possible. And like the original hackers it’s about a hunger for knowledge, which is why we’ve laid out the best tutorials and the most useful features from the most recent issues of Linux Format as a feast for the hungry hacker to devour. You’ll learn things like how to stay anonymous online; how to secure your phone; how to take control of all your data and set up a personal cloud and even learn a few web cracks that the ‘Dark Side’ may try to fling in your direction. We think this year’s Hacker Manual is the best one yet. Tuck in and enjoy the hack!

Neil Mohr, Editor

Guru Guides are designed to help experienced technology users dive deeper into a subject. Whether you’re learning a new programming language or planning to start a new business, each book aspires to be…

● A reference you can keep

on your desk or next to your computer and consult time and time again when you need to know how to do something or solve a problem

A challenge – we know that you know the basics so instead of patronising you we’ll suggest new things to try and help you take your knowledge to the next level

A teacher – helping you develop your skills and take with you through your life, applying them at home or even in the workplace

How are we doing? Email techbookseditor@futurenet.com and let us know if we’ve lived up to our promises!

The Hacker’s Manual 2015 | 5

Welcome & Manifesto

Welcome!


Contents Dive into the world of hacking with this indepth manual that covers the big topics from the Linux kernel and wider open-source OS to hacking servers, the web and beyond.

6 | The Hacker’s Manual 2015

Linux

Privacy

Hack the kernel and dive into the open source OS that we all know and love

Keep it secret, keep it safe. Tools and hacks to block GCHQ and the NSA

10

Next-gen Linux

38

Anonymising distros

18

Build your own kernel

45

Beat the NSA

24

Master package managers

54

Full-drive encryption

28

Discover Arch Linux

56

Build your own VPS

32

Using Rescatux

60

Cryptography explained

65

Android security


Contents

Hardware

Networks

Internet

Cool hacks to bust open hardware and get it to run whatever OS you want

Take control of your LAN and your servers with protocols and monitoring tools

How to take control of the world wide web, hack servers and stay safe

72

Linux on Chromebooks

118 Master the basics

162 D eploy OwnCloud and kick out Google forever!

76

Free Android

122 Go next-gen IPv6

80

Crack open UEFI

126 Build a log server

166 D iscover how you can hack and protect servers

84

Build a Linux PC

130 M onitor packets with Wireshark

174 T ake control of your email with your own webmail

94

Advanced file systems

98

Build your own NAS

134 Samba and Windows 141 Docker and virtual servers 104 Build your own robot 150 Ldap authentication 108 OpenGL on the Pi 156 Discovering Dtrace 112 Hack your router

The Hacker’s Manual 2015 | 7


em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails sk.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren undle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate : dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pyg lock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame. n/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refres evelopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_ rmat.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro dd_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_ Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) cl TARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg me::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru spec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_ otice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th mport pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = f ndrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-> star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev stall bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format o_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priorit bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone mport randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = ars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(us et(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0 rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { h ormat.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:m erver validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from it() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrang vent in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --versio nit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { rende atus: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ ef due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_ST ode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while Tru pe == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numst star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails sk.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren undle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate : dd(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pyg lock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame. n/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refres evelopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_ rmat.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro dd_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_ Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) cl TARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg me::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru spec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_ otice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th mport pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = f ndrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-> star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev stall bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format o_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priorit bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone mport randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = ars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(us et(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0


Linux hacks Dive into the kernel and deeper OS to take control of your systems 10

Next-gen Linux Get next-gen features of the kernel today with our guide to the latest developments.

18

Build your own kernel Take complete control and build the Linux kernel you want from the source.

24

Package management Discover how Linux controls and updates your software through apt-get and more.

28

Arch Linux Install the rolling release distro that all the expert hackers love and you will too.

32

Recover systems with Rescatux When it all goes wrong roll out Rescatux to recover lost files, partitions and more.

The Hacker’s Manual 2015 | 9

Linux hacks | Contents

s new todolist --skip-test-unit respond_to do |format| if @ nder json: @task.errors, status: :unprocessable_entity } $ :due_at_is_in_the_past def due_at_is_in_the_past errors. ygame.display.set_mode((640, 480)) clock = pygame.time. .event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/ star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { sh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group d_to do |format| if @task.update_attributes(params[:task]) ocessable_entity } $ bundle exec rails generate migration _in_the_past errors.add(:due_at, ‘is in the past!’) if due_at lock = pygame.time.Clock() stars = for i in range(MAX_ game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < ubyracer”, “~> 0.11.4” group :development, :test do gem _attributes(params[:task]) format.html { redirect_to @task, generate migration add_priority_to_tasks priority:integer he past!’) if due_at < Time.zone.now #!/usr/bin/en python for i in range(MAX_STARS): star = [randrange(0, 639), umstars = 100; use Time::HiRes qw(usleep); use Curses; >clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem t.html { redirect_to @task, notice: ‘...’ } format.json { head ty_to_tasks priority:integer $ bundle exec rake db:migrate e.now #!/usr/bin/en python import pygame from random = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] sleep); use Curses; $screen = new Curses; noecho; curs_ { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] 0” $ gem install bundler $ gem install rails --version=3.2.12 head :no_content } else format.html { render action: “edit” migrate $ bundle exec rake db:migrate $ bundle exec rails random import randrange MAX_STARS = 100 pygame. ge(1, 16)] stars.append(star) while True: clock.tick(30) for curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] _x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } ion=3.2.12 $ rbenv rehash $ rails new todolist --skip-tester action: “edit” } format.json { render json: @task.errors, bundle exec rails server validate :due_at_is_in_the_past TARS = 100 pygame.init() screen = pygame.display.set_ ue: clock.tick(30) for event in pygame.event.get(): if event. tars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); r_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; s new todolist --skip-test-unit respond_to do |format| if @ nder json: @task.errors, status: :unprocessable_entity } $ :due_at_is_in_the_past def due_at_is_in_the_past errors. ygame.display.set_mode((640, 480)) clock = pygame.time. .event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/ star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { sh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group d_to do |format| if @task.update_attributes(params[:task]) ocessable_entity } $ bundle exec rails generate migration _in_the_past errors.add(:due_at, ‘is in the past!’) if due_at lock = pygame.time.Clock() stars = for i in range(MAX_ game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < ubyracer”, “~> 0.11.4” group :development, :test do gem _attributes(params[:task]) format.html { redirect_to @task, generate migration add_priority_to_tasks priority:integer he past!’) if due_at < Time.zone.now #!/usr/bin/en python for i in range(MAX_STARS): star = [randrange(0, 639), umstars = 100; use Time::HiRes qw(usleep); use Curses; >clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem t.html { redirect_to @task, notice: ‘...’ } format.json { head ty_to_tasks priority:integer $ bundle exec rake db:migrate e.now #!/usr/bin/en python import pygame from random = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] sleep); use Curses; $screen = new Curses; noecho; curs_ { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] 0” $ gem install bundler $ gem install rails --version=3.2.12


Linux hacks | Cutting-edge Linux

Linux hacks

GET THE TECH OF

20 15 With the enthusiasm of a kid using the newest and shiniest toys, we show you how to play with the latest Linux software.

W

e often hear how wonderful Linux is for older hardware, and it is. Linux enables many users to keep using systems that others would be forced to discard. But statements like that are also doing Linux a disservice, and give the impression that it’s just a poor man’s operating system for hardware that’s no longer up to running the latest and greatest [<cough> - Ed] version of Windows. Nothing could be further from the truth, Linux has some cutting edge software available, although the mainstream distros do not always reflect this. The distro development teams have to worry about compatibility and stability, so they generally

default to using stable, well tested software. Even popular distros such as Ubuntu, which uses Debian Testing packages and has a reputation for being forward looking, doesn’t use the very latest software. So what do you do if you want to try life on

way. This is the stuff that may well appear in your favourite distribution next year, but we will show you how you can try it now. You can see what the future holds, as we show you how to install it. We will also look at some of the pitfalls surrounding doing this, after all, there is a reason the distros don’t include the latest experimental code, and show you how to try it without risking your system or your sanity. It doesn’t really matter which distro you currently use, although some do make it easier than others (such as Arch or Gentoo) but something like the ubiquitious Ubuntu (or one of its derivatives, such as Linux Mint) or OpenSUSE or Fedora are also an excellent base for experimentation.

“This is the stuff that may well appear in your favourite distribution next year.”

10 | The Hacker’s Manual 2015

the bleeding edge? What software is out there that the distros are not yet using and how can you try it for yourself? Over the next few pages, we will look at some of the new technologies being developed for Linux, but not in a theoretical


Linux hacks

Perform a heart transplant on your Linux OS.

L

et’s start with the heart of a Linux system: the kernel. New versions are released every couple of months, with minor updates in between. So the kernel supplied with your new distro will already be slightly behind, more so if the distro sticks with the long-term kernel releases. Should you be concerned and do you need to update? The answer to those questions is usually ‘no’ but there are some perfectly good reasons for updating to the latest available: Security: It may be that bugs have been discovered in the version you are using that affect the security or stability of your system. In this case, a minor update will be released with the fix and your distro will provide it through their normal updates system. Drivers: If you have some really new hardware, the drivers may not have been included until after the version your distro provides, so you need to compile your own. Features: You may want access to a feature in a newer kernel. For example, if you use the btrfs filesystem, it’s still developing quite rapidly so a more recent kernel may be a good idea. Patches: You want to apply a patch to the kernel that adds or alters a feature. Shiny: Geeks love shiny new stuff, so you may be tempted to use a later kernel just because you can.

Rite of passage Using a kernel version not supplied by your distro means downloading the source and compiling it yourself. This is often considered a rite of passage among Linux users, and certainly gives you bragging rights to be able to say you built your own kernel. However, there’s no mystique to the process and recompiling the kernel is actually safer than building anything else from source. This is because the kernel is built as a separate file in /boot, loaded by your bootloader, but the old kernel is still there, the new one is just another file with a slightly different name. Even if you manage to build a kernel that will not boot, you can simply select the old kernel from your boot menu and try again. While it is possible to compile a kernel as a normal user and then switch to root to install it, the process is simpler if you are logged in as root before you start. Download the kernel you want from https://kernel.org and unpack the tarball into /usr/src. If you want to apply a kernel patch, this is the time to do it. The process for applying patches depends on the individual case, so follow the instructions that came with the patch. Now you need to configure the kernel. You could do this from scratch, but it is easier if you start with your current kernel configuration. Some distros enable the feature that makes the current kernel’s configuration available from /proc/config.gz. In that case, cd into the directory for your new kernel and copy this to the configuration file: cd /usr/src/linux-3.x.y zcat /proc/config.gz >.config

Once you have a configuration file in place, you need to tweak it to take the new options into account. There are a number of ways to do this, and for a simple update to a newer version the easiest option is to run: make oldconfig This prompts you for any changes between the current saved configuration and what is available in the new kernel. You normally have four options: y, m, n or ?. The first builds the option into the kernel, the second builds it as a loadable module, you have probably already guessed that n disables the option, while ? shows you some help text then asks the question again. The other options provide a graphical(ish) configuration program. make menuconfig make xconfig Menuconfig is an ncurses-based program, so you can use it over SSH or in a console, xconfig opens a fully graphical

“Recompiling the kernel is actually safer than building anything else from source.” tool. With either method you can browse and select options and view help text. You can also search for a particular option by pressing / in menuconfig or Ctrl+F in xconfig. Then click on the item you want in xconfig, or press the number alongside it in menuconfig to jump to that setting. Once configured, you can compile and install the kernel and module like this: make all make modules_install make install Sometimes the feature or driver you want is included in the current kernel but not enabled in the build from your distro. In such cases you don’t need to update the kernel but you will need to recompile the existing one.

Update the initrd You may also need to build a new initrd before running grub-mkconfig or update-grub, the exact command for this is distro-dependent, but you can avoid it altogether by building everything you need to mount the root partition – such as SATA drivers and the filesystem used on the root partition – into the kernel and not as modules. You would then lose your graphical boot splash screen, but if you are running cutting-edge software, you probably want to be able to see the boot messages anyway.

When it comes to configuring your kernel, you have a choice of interfaces: installing the mousefriendly xconfig and the shellfriendly menuconfig.

The Hacker’s Manual 2015 | 11

Linux hacks | Cutting-edge Linux

The Linux kernel


Linux hacks | Cutting-edge Linux

Linux hacks

Wayland Try out the replacement windowing system for the ageing X11.

O

For now, you will need to edit weston. ini to get a functional desktop using Weston. With software still in testing, the friendly graphical editors tend to come later on.

ne of the most talked about projects that we are still waiting for is Wayland. This is intended to replace the ageing X window system, with its somewhat tortuous client/server model. Wayland has been in development for about five years already, with several announcements from distros, such as Fedora that it would be in their next release, followed with “it’s not quite ready, maybe the release after”. Wayland is actually available now, although not all applications work with it. You can install it from a package in the usual way or get the source from http://wayland. freedesktop.org, but you may find that Wayland is already installed on your distro. The latest Ubuntu and Fedora releases certainly have it pre-installed. However, installing Wayland itself will not change anything. Wayland is basically a library, you need a compositor to be able to replace X. But what is a compositor? This is the software that actually draws your screen, rendering the windows over the background and updating the image as objects are opened, closed, resized and moved. With current systems, the compositor does most of the work, making much of X redundant. This is one of the advantages of Wayland; it acts as a simple interface between programs and the compositor and between the compositor

and the kernel, which handles input events. This gives a simpler, lighter and faster system with each part of the software stack handling its assigned tasks and Wayland handling the intercommunication. The reference compositor from the Wayland project is called Weston, and you need to install that, too. You can run a Weston session in a window on X, just run weston in a terminal, but that doesn’t show you the true picture. To launch a full Wayland/Weston desktop, log out of X and into a virtual console and run: weston-launch Do this as a normal user, not as root. You will see a very basic desktop open with nothing but a terminal icon at the top right. Wayland comes with some example programs that you can run from this terminal, such as: weston-image – an image viewer. weston-pdf – a PDF viewer. weston-flower – a graphical demonstration. weston-gears – runs GLXgears, for comparison with X.

Do something useful Demo programs are very nice, but not that useful. To get a more functional Weston desktop, you will need to edit ~/.config/weston.ini, which you can think of as the Westonequivalent of .xinitrc which specifies what to run when the desktop is loaded. It follows the standard INI file format of a section name in brackets, followed by one or more settings for that section, like this [core] modules=desktop-shell.so,xwayland.so [shell] background-image=/home/nelz/wallpaper.png background-color=0xff000000 panel-color=0x90ffffff The core section loads the modules you want, xwayland is used to run X programs on Wayland. The shell section sets the basics of the desktop, here we are setting the desktop background and the colour and transparency of the panel at the top of the screen. You can check the appearance by running weston in an X terminal to open it in a window, but it doesn’t do much yet, let’s add something to the launcher: [launcher] icon=/usr/share/icons/hicolor/24x24/apps/chromium-

What is wrong with X? The main problem with X is that it’s a huge software stack that tries to do everything for the graphical environment, when much of that can be done elsewhere. The architecture also means that everything has to go through the X server. Clients don’t tell the compositor about windows being opened or closed, they tell the X server. But the X server doesn’t deal with such matters,

12 | The Hacker’s Manual 2015

it passes the message on to the compositor, and the response takes a similarly tortuous route. Similarly, input events, which are generated by the kernel these days, have to go via the X server. So we have this complex piece of software acting as a messenger, and not a very efficient one at that. It’s important to realise that the

Wayland developers have not set themselves up as competition to the X.org developers, there are X.org devs working on Wayland. The Wayland project is an attempt to bring the graphical desktop infrastructure up to date. It has taken a lot longer than some expected, as is so often the case, but it is definitely getting there and well worth a try.


ENJOYED READING THIS MAGAZINE? Subscribe and make great savings at www.myfavouritemagazines.co.uk


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.