Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore OpenSourceForYou201504

OpenSourceForYou201504

Published by E-book Bang SAOTHONG Distric Public library, 2019-12-11 22:00:10

Description: OpenSourceForYou201504

Search

Read the Text Version

Make Your Own IVR Manage Your Marketing Activities With Asterisk With CampaignChain Volume: 03 | Issue: 07 | Pages: 108 | April 2015 Awesome Tools For Web Development! Creating Great Web Experiences With Drupal Bootstrap: Building An Interactive Web Page Try Out The Eclipse Editor To Create Web Apps Developing Games For The Web Android Lollipop: What’s In It An Interview With Sushanto Mitra, For Enterprises? Founder And CEO, Lead Angels



www.unotechacademy.com Industry is adopting Open Source Are you adopting the skills? Open Doors to a career in Open Source COURSES OFFERED RRHHCCE77(1(21020hohuorusr)s) PoPsotgsrtgeSreQsLAAddmminin OOpepneLnDldAaPp (40 hours) PJBHoPs&s AMdYmSqinl PJBHoPs&s AMdymSqinl (4(040hohuorusr)s) AAppaacchheeSSptarckk (40 Hours) JjQquery (40 hours) (40 Hours) RHEV (40 hours) (4(400HHoouursrs)) SpSrpinrigng&HHibibeerrnnaattee (4(400HHoouursrs) ) Nginnix (40 hours) For more details, contact Omar on (+91 887 968 5760) or write to [email protected] Unotech Academy, #139, DamjiShamji Bldg. Nr. BMW service Center, Mahakali Caves Rd, Andheri (E). Mumbai. 400093

Contents Developers 20 Talking to the Kernel through Sysfs 30 How to Install Moodle on a LAMP Server 32 Use Haskell to Access Two Popular Databases 37 Bootstrap: Building an 43 Develop Multi-device Web Based Games with HTML5 Interactive Tourism Web Page 40 Writing a Basic Framebuffer Driver 45 Popular Open Source IDEs for Web Development 47 Qt5: GUIs with QtQuick and QML 54 The Link+ Project for Linux Kernel Developers 59 Developing a Web-app Using the Eclipse Editor 68 Face-off with Sizeof() 63 Selenium: A Popular Software Testing Tool You Can Rely On 73 Creating an Awesome Web REGULAR FEATURES Experience with Drupal 07 Offers of the Month 24 Editorial Calendar ADmin 08 You Said It... 104 Tips & Tricks 79 FSlint: A ‘Laundromat’ for 10 FOSSBytes File Systems 87 An Overview of OpenShift 4 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com



Contents Editor 84 Make Your Own IVR with Asterisk Rahul chopRa For YoU & me Editorial, Subscriptions & Advertising 91 Ten Android Apps for Everyday Delhi (hQ) D-87/1, Okhla Industrial Area, Phase I, New Delhi 110020 Use on Your Smartphone Ph: (011) 26810602, 26810603; Fax: 26817563 E-mail: [email protected] 96 Manage Your Marketing Missing Issues Activities with CampaignChain E-mail: [email protected] BeNGAlURU Ph: (080) 25260394, 25260023 E-mail: [email protected] Customer Care e-mail: [email protected] Back Issues Kits ‘n’ Spares New Delhi 110020 Ph: (011) 26371661, 26371662 E-mail: [email protected] Advertising CheNNAi Ph: (044) 42994363 E-mail: [email protected] hYDeRABAD Ph: (040) 67172633 E-mail: [email protected] KolKAtA Ph: (033) 22294788 E-mail: [email protected] mUmBAi Ph: (022) 24950047, 24928520 E-mail: [email protected] PUNe Ph: (020) 40147882 E-mail: [email protected] GUJARAt Ph: (079) 61344948 E-mail: [email protected] JAPAN Tandem Inc., Ph: 81-3-3541-4166 E-mail: [email protected] 94 Android Lollipop: What’s in it open gUrUs SiNGAPoRe for Enterprises? Publicitas Singapore Pte Ltd 25 Using Scilab with the Ph: +65-6836 2272 E-mail: [email protected] McCabe-Thiele Method UNiteD StAteS 98 Audio Video Bridging: E & Tech Media Ph: +1 860 536 6677 Evolution of Multimedia E-mail: [email protected] Streaming Technology ChiNA ColUmns Power Pioneer Group Inc. Ph: (86 755) 83729797, (86) 13923802595 16 CodeSport E-mail: [email protected] 18 Exploring Software: Spark: tAiwAN J.K. Media, Ph: 886-2-87726780 ext. 10 Exploring Big Data on a Desktop E-mail: [email protected] Exclusive News-stand Distributor (India) iBh BooKS AND mAGAziNeS DiStRiBUtoRS ltD Unit No.10, Bezzola Complex , Opp. Suman Nagar, Sion Trombay Road, Chembur, Mumbai – 400 071 Phones : 022 – 40497401 /02 E-mail: [email protected] Printed, published and owned by Ramesh Chopra. Printed atTara Art Printers Pvt Ltd, A-46,47, Sec-5, Noida, on 28th of the previous month, and published from D-87/1, Okhla Industrial Area, Phase I, New Delhi 110020. Copyright © 2013. All articles in this issue, except for interviews, verbatim quotes, or unless otherwise explicitly mentioned, will be released under Creative Commons Attribution-NonCommercial 3.0 Unported License a month after the date of publication. Refer to http://creativecommons.org/licenses/by-nc/3.0/ for a copy of the licence. Although every effort is made to ensure accuracy, no responsibility whatsoever is taken for any loss due to publishing errors. Articles that cannot be used are returned to the authors if accompanied by a self-addressed and sufficiently stamped envelope. But no responsibility is taken for any loss or delay in returning the material. Disputes, if any, will be settled in a New Delhi court only. SUBSCRIPTION RATES PeriodNews-stand price You Pay Overseas 101 “Start-ups don’t just require Year (`) (`) funds. They need mentorship and guidance as well!” DVD Of The Month Five 6000 3600 — —Sushanto Mitra, founder and Try out something Three 3600 2520 — CEO, Lead Angels new and fresh One 1200 960 US$ 120 106 Kindly add ` 50/- for outside Delhi cheques. Please send payments only in favour of EFY Enterprises Pvt Ltd. Non-receipt of copies may be reported to [email protected]—do mention your subscription number. 6 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

offerS THE monTH mfOorneneeth 2000 Rupees OffeArpHvruailrlir2dy0!t1il5l!30th Coupon (Free Trial Coupon) Free Dedicated Server Hosting No condition attached for trial of our for one month cloud platform Subscribe for our Annual Package of Dedicated Server Hosting & enjoy one month free service OffeArpHvruailrlir2dy0!t1il5l!30th Enjoy & Please share Feedback at [email protected] For more information, call us For more information, call us on on 1800-209-3006/ +91-253-6636500 1800-212-2022 / +91-120-666-7718 www.esds.co.in www.cloudoye.com Get 10% 35% discount off & more “Do not wait! Be a part of Reseller package special offer ! the winning team” OffeArpHvruailrlir2dy0!t1il5l!30th Free Dedicated hosting/VPS for one OffeArpHvruailrlir2dy0!t1il5l!30th Get 35% off on course fees and if you appear month. Subscribe for annual package for two Red Hat exams, the second shot is free of Dedicated hosting/VPS and get Contact us @ 98409 82184/85 or one month FREE Write to [email protected] Contact us at 09841073179 or Write to [email protected] www.space2host.com www.vectratech.in Get Get 25% PACKWEB PACK WEB 12 Months HOSTING Off Free ProX Time to go PRO now Pay Annually & get 12 Month Free Considering VPS or a Dedicated Services on Dedicated Server Hosting Server? Save Big !!! And go with our ProX Plans OffeArpHvruailrlir2dy0!t1il5l!30th Subscribe for the Annual Packages of OffeArpHvruailrlir2dy0!t1il5l!30th Dedicated Server Hosting & Enjoy Next 25% Off on ProX Plans - Ideal for running 12 Months Free Services High Traffic or E-Commerce Website For more information, call us on Coupon Code : OSFY2014 1800-212-2022 / +91-120-666-7777 Contact us at 98769-44977 or Write to [email protected] www.goforhosting.com www.prox.packwebhosting.com Fees BIG DATA ANALYTICS Register in EMBEDDED SOFTWARE DEVELOPMENT Rs. 15000/- Advance to COURSES AND WORKSHOPS (SC/ST/PH-50% using hadoop eco-system receive a Concession) School of Embedded special Software Development discount Faculty - Babu Krishnamuthy Venue: Malleshwaram, Bangalore Visiting Faculty/ CDAC/ACTS Porting Embedded RTOS to an ARM platform Qualification: Degree / Diploma Certificates Trainging Contents: Introduction, HDFS School of embedded software, Bangalore Will Be Maoreduce, Administration, Hbase, Hive, Pig Short-term Courses Awarded Sqoop, Flume, Oozie, Hadoop2.0 www.schoolofembedded.org For more information, call us on Email: [email protected] Balajee. K.M, Asst, Director, Mob.: 9900226980, 080 41100557 Contact : +91-98453-65845 www.msmedibangalore.gov.in

YOUSAID IT The most informative magazine on how to configure the Globus toolkit . Thanks a lot and keep up the good work I am a regular reader of OSFY. I have tried many tech magazines but none of them are as informative —Elisha Robinson, and useful as yours. I liked the article ‘The Way [email protected] FreeBSD Jails Work’ published in the February issue of OSFY. ED: Thanks a lot for the feedback. We cherish our readers' views and with every edition, we try to bring Could I request you to carry an article on tape out a better product. It really makes us feel good to drives in your ‘Buyer’s Guide’ section? And last of know that OSFY (or rather, LFY) was instrumental all, I would like to congratulate your team for such in your switching to open source. It’s true that we a tremendous effort in making this magazine so have not covered grid computing recently. Do keep useful to us. reading the magazine, as we are trying to focus more on such topics. Feel free to continue sending us I would also like to give a big thumbs up to your your feedback. magazine’s distribution team for ensuring that I get my monthly issue on time. In appreciation of the article on Hadoop —Shivram Sharan, [email protected] It's been an amazing experience following OSFY and I am very thankful to the OSFY team. Each and every ED: Thanks a lot for the feedback. It feels great when topic published has its own advantages but the article readers tell us how they benefited from our magazine. on Hadoop (in the March 2015 edition of OSFY) truly We will convey your feedback to the author of the enlightened me enough to be able to work on multi- article on ‘The Way FreeBSD Jails Work’. We will node Hadoop clusters. Keep posting more about surely try and implement your suggestion and come up Hadoop and HPC in forthcoming issues, too. with a ‘Buyer’s Guide’ on tape drives. Thanks and regards, Our magazine’s circulation and distribution team —Tapas Sen, will be more than happy to get a pat on the back for their efforts. Keep sharing your feedback with us. [email protected] A request to feature Gridway ED: We always value our readers and try to feature topics that interest them. Thanks a lot for the feedback. I am a regular reader of OSFY (and earlier of It really makes us feel good to know that you love most LFY) for the past three years. I must tell you that LFY of the articles published in OSFY. So keep reading the was the reason I made a complete switch to open magazine and writing in to us. source. I wish that you would have a special feature about how to implement grid computing in Gridway. I would also appreciate it if you could feature an article Share Your Porlesauseggseesntdioynosurtoc:omments The Editor, Open Source For You, D-87/1, Okhla Industrial Area, Phase I, New Delhi 110020, Phone: 011-26810601/02/03, Fax: 011-26817563, Email: [email protected] 8 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com



FOSSBYTES Powered by www.efytimes.com Google rolls out Android 5.1 Lollipop MakuluLinux Cinnamon to improve stability and performance upgraded to 64-bit version Google has announced that it is now rolling out MakuluLinux Cinnamon has been Android 5.1 Lollipop, an upgraded to a 64-bit version. This update which improves Linux distro is based on the Debian stability and performance. testing branch, Jessie, and it’s It has several new features, known to provide stability, speed including official support and modern desktop features. for multiple SIM cards, high definition voice Until now, MakuluLinux was calling on phones that support this feature, device protection and more. This would a 32-bit distro only, but now it be the first major update to Android Lollipop since its release. has an upgraded edition too. The Cinnamon flavour is quite popular Google made the announcement on its official Android blog, where it has been because it is lightweight. It will mentioned that 5.1 Lollipop will also provide enhancements such as the ability not only be compatible with 64-bit to join Wi-Fi networks and control paired Bluetooth devices directly from Quick machines, but it also integrates a Settings as well. With Android Lollipop 5.1, more than one SIM card can be used on new and interesting feature that a device with multiple SIM slots. Lollipop 5.1 will also come with high definition allows users to save a snapshot of voice calling on mobile phones. their current desktop, package it and install it on another computer. Google has added an additional feature called ‘Device Protection’ which MakuluLinux is already very protects your phone when you lose it or if it gets stolen. It will remain locked comfortable for new users. It’s until you sign in with your Google account, even if someone resets your device based on Debian, and it directly to factory settings. competes with Linux Mint. Ubuntu MATE 15.04 to ship with Tilda terminal app The developer has posted, “This release is special for so many The Ubuntu MATE team, which reasons. It is sure to mark a major is currently enjoying its official milestone, not just for Makulu, community flavour status, is busy but considering what is inside, the providing details about the new whole of the Linux world. Never features that are being shipped before has Linux offered such with Ubuntu MATE 15.04—the options as we have done in this latest being the addition of Tilda. release, and what is more, we made it so easy to use. Makulu now Tilda is a ‘dropdown’ offers a built-in constructor tool terminal application which that lets you quickly and easily is quite similar to its popular create a 100 per cent snapshot of alternatives like Guake. It is an important application for Ubuntu MATE. your LIVE system as it is, and Dropdown terminals are necessary to some extent. You will not be required to save it into an ISO that can be then open an app any more with this application, as you will now only have to hit re-installed on a new computer. It a hot key (for example F12 in Ubuntu MATE) to open and then shut it down. comes complete with a live mode, Tilda has several customisation and configuration options, and it supports installer and full EFI/Secure boot.” multiple tabs too. It is available for installation on most versions of Ubuntu and related flavours, directly from the repositories. As per the changelog, the Linux kernel is now at version Latest Intel Linux graphics drivers now available 3.16, the Cinnamon desktop environment has been upgraded A new version of the latest Intel Linux graphics drivers installer is now available to version 2.2.16, EFI support has for download, which gives users an easy way to upgrade Intel graphics drivers on been integrated, and firewall and supported operating systems. antivirus applications have also been added. ‘Intel Graphics Installer For Linux’ is a free utility that can be used to install the latest graphics and video drivers for Intel graphics hardware. It is developed and maintained by Intel Open Source Technology Center. It allows you to stay up to date 10 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

FOSSBYTES with the latest enhancements, optimisations and fixes released for Intel’s graphics The first automotive bus with hardware. The installer is currently available for Ubuntu and Fedora distributions. a Linux based design is out! Deprecated status allows people to use the tool to remove or install an Germany based Technische Universität older version of the graphics stack. This time round, Ubuntu 14.10 and Fedora München (TUM) is unveiling a 21 are formally supported, with Ubuntu 14.04 LTS and Fedora 20 entering two-tier automotive service bus for ‘deprecated’ status. car computers. This service will be available on a control unit running The tool no longer performs major xserver-xorg upgrades as part of its update Linux on a PandaBoard. It is based on process. Utopic users can make full use of the tool to upgrade to the Intel 2014Q4 the Java based Open Service Gateway graphics stack. A number of improvements to the standard Intel Linux 2D and 3D Initiative (OSGi). drivers have been seen during the 2014 Q4. These include support for Broadwell and CherryView CPUs, preparations for Skylake processors, Backlight and power Technische Universität München sequencer fixes and revamped Vblank handling. (TUM) has open-sourced an automotive computer bus design developed as part Git 2.3.3 released with several bug fixes and of its ‘Visio.M’ (Visionary Mobility) performance improvements electric car project. The automotive service bus is designed to handle The third maintenance release of the stable Git 2.3 branch has been released. today’s increasingly computerised cars, The new release integrates several bug fixes and includes many performance which often involve up to 80 different improvements in the popular distributed revision control system. electronic systems. Git allows developers to The system is controlled by a cross- interact with GitHub to upload platform central control unit built by the source code of programs. As IAV. A separate, Web-enabled control per the changelog, in the newly unit responsible for driver and Internet released Git 2.3.3, corrupt input communications interacts wirelessly in the ‘git diff –M’ command has with a touchscreen, which in the case of been fixed, which means it will no the Visio.M, is an Apple iPad. more cause a segfault. Description of the ‘grep-h’ command has been improved, too, and documentation for the ‘git remote add’ command has been modified so that Visio.M’s OSGi hardware platform information about ‘-tags’ and ‘-no-tags’ arguments is more clear. is based on a hardware design that runs Linux on an open-spec PandaBoard, Now ‘unsigned char’ will be used to store values that range from 0-255, which in turn is equipped with a Texas unnecessary dirstat based on lines have been removed from the ‘git diff --shortstat Instruments 1GHz, dual-core, Cortex-A9 --dirstat=changes’ command, and some documentation has also been modified to OMAP4430 system-on-chip. make the interaction between the submodule.*.update configuration and the ‘git submodule update’ command more clear. Although the bus uses a typical CAN network, it breaks away from An update has also been made to the ‘git apply’ command so that it correctly traditional automotive bus designs, reads, creates, updates and removes paths from the directory or outside the which are based on 100-year old working tree. In the new version, the ‘git daemon’ command will also not look technology. The new bus architecture for hostnames if the ‘%IP’ and ‘%CH’ interpolations are not sought for. The resembles that of dual-layer smartphone ‘interpolated-path’ option of the ‘git daemon’ command will also not insert any architecture, securely isolating string client in the new release. driving and safety functions from communications and Internet functions. VMware to expand desktop virtualisation to Linux All connected firmware components can be updated, appended or deleted VMware is expanding its Horizon desktop over the Internet. virtualisation solution. The software suite will soon deliver virtual Linux desktops The two-seat Visio.M has a range of over a network. VMware Horizon 6 is a comprehensive desktop and application 160km, and the 15kW motor supports virtualisation solution to deliver and manage any type of enterprise application a maximum speed of 120km/h. The and desktop, including physical desktops and laptops, virtual desktops and lightweight car is powered by a applications, and employee-owned PCs. 13.5kWh Li-Ion battery, which can be recharged in under four hours. The The software is designed to allow administrators to control their organisation’s battery weighs 85kg, compared to Linux virtual desktops with the same tools that they use to manage their Windows 450kg for the car (without the battery). virtual desktops. The company has launched an early-access program for customers to test a www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 11

FOSSBYTES SUSE launches its own open version of Horizon 6 that can package server-based Red Hat and Ubuntu Linux source storage solution desktops, so they can be accessed from remote computers and mobile devices. SUSE has released its own storage Customers can use VMware Horizon 6 to leverage the power of solution for enterprise customers. The virtualisation, and transform their desktops into secure virtual workspaces to open source storage is powered by embrace business mobility. Ceph’s Firefly open source project and the solution is highly scalable. Virtual desktop infrastructure (VDI) software can be handy for organisations that have mobile workers who need to access applications Nils Brauckmann, GM, SUSE, said and desktop environments from multiple devices. Virtual desktops can also that SUSE Enterprise Storage is a highly simplify the large-scale management of software and operating systems. scalable and resilient software storage solution that lets small organisations The company has updated Horizon 6 with additional capabilities for and enterprises move from proprietary, managing 3D images and for integrating into software defined networks (SDNs). hardware based storage to software based storage, which ensures great functionality Google Code to close down! at negligible cost. The search giant is closing down Google Code because there are other SUSE has designed this software alternatives available on the Web. Google Code was a competitive alternative based storage solution with easy back-up to SourceForge for open source project hosting. and archiving capabilities for enterprise customers. It has priced this solution well— Google launched the project in 2006 because it was unhappy with the charging $0.001 per GB for enterprise ‘limited’ options available to the open source community. But since then, a “… users. SUSE’s vision has been to bring wide variety of better project hosting services” such as GitHub and Bitbucket cost-efficient and highly scalable storage have moved to the forefront. solutions to enterprises. The companies can build their storage space using commodity In May 2013, Google off-the-self servers and disk drives. also shut down Google Code Download services. In Enterprise customers can save a lot order to “…meet developers of the money being spent on expensive where they are,” Google hardware with this solution. SUSE itself has transferred nearly a thousand of its own open source projects to claims that this software based storage the popular coding repository GitHub. solution is 30 per cent less expensive than conventional NAS solutions and GitHub isn’t just a place to download, but it has become a fantastic and 50 per cent less expensive than average integral part of the development process in a way that neither Sourceforge nor capacity optimised disk array systems. Google Code ever were. The migration of developers to the new services has SUSE has designed this solution to be left Google Code dealing with a deluge of spam and abuse. very flexible and scalable to serve an enterprise’s need for more storage as the The end of Google Code will be based on a timed approach. As of March company grows. Customers can rapidly 12, 2015, all new project creation has been disabled. On August 24, 2015, the boot new virtual machines with SUSE site goes read-only and will effectively disappear on January 25, 2016. Enterprise Storage. The service offers fault-tolerant enterprise disk storage. Linux kernel 3.19.1 released SUSE has invested in OpenStack in The first point release of Linux 3.19 kernel was announced the past so the company has no intentions with immediate availability for download. Linux kernel of competing with it. Red Hat already has 3.19.1 is the current stable branch of the Linux kernel. its own software based storage solution, so SUSE needed a cloud based storage As per the changelog, the first point release solution to help serve the needs of its of Linux kernel 3.19 comes with a number customers. It has integrated this new of improvements to several architectures storage solution in SUSE OpenStack including ARM, x86, PowerPC, MIPS, ARM64 Cloud to provide flexible access. SUSE as well as s390. The release also includes Enterprise Storage can also be used as a updates to drivers, file systems, networking, stand-alone storage solution. sound and security. Developer Greg Kroah-Hartman said in the mailing list announcement, “I’m announcing the release of the 3.19.1 kernel. All users of the 3.19 kernel series must upgrade.” The 3.19.1 version brings updated 12 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

FOSSBYTES drivers for wireless, USB, ACPI, Bluetooth (ath3k), CPUFreq, HID, MD/ Apple launches ResearchKit RAID, MMC, DVB, PCI, SCSI, TTY, and XEN. The XFS, UDF, NFS, framework to help medical JFFS2, OCFS2, EXT4 and Btrfs file systems have also received several research improvements, and some Ceph, IPv4 and SunRPC issues have also been fixed. The upcoming Ubuntu 15.04 (Vivid Vervet) will be based on the At the launch of Apple Watch, a new Linux 3.19 kernel, and it already includes packages based on the Linux software framework was announced by kernel 3.19.1. the company. This is expected to turn 700 million iPhones into medical diagnostic VLC 2.2 launched for Windows, Mac, Linux and leading tools. This is an open source framework, mobile platforms called ResearchKit. It will allow medical researchers to create diagnostic apps to tap The favourite media player of millions worldwide, into the screens and accelerometers on the VLC, has released its 2.2 ‘Weathermax’ version which iPhone, and also tap data from HealthKit integrates some new features for the desktop. This apps. The first five apps built with the release includes a built-in extension gallery. open source framework have been made available and will help diagnose several New features can be easily added to VLC with kinds of disorders. just a few clicks through Tools > Plugins and Extensions. The new version has also added At the event, details of the special the playback resume feature, which has been applications were provided by Apple’s requested for since a long time. When a senior VP of operations, Jeff Williams. video or audio file is reopened, a ‘Continue These applications include the mPower Playback’ pop-up appears and in this way app, which can gauge the effects of the desktop version comes on par with its Parkinson’s disease. This app has been mobile counterpart. Another major real- developed jointly by the University of life bug has been resolved too, which Rochester, Xuanwu Hospital at Capital used to auto-rotate videos that are recorded on a smartphone or tablet. Medical University in Beijing, and Sage Bionetworks. On stage at the launch of Some usual codec updates have also taken place like support for Ultra Apple Watch, some tests within the app HD, VP9 and H.265, and ‘compatibility’ fixes for a series of obscure were demonstrated by Williams. These file formats. Some other changes include GPU zero-copy decoding, showed how the app could measure hand which will ensure faster performance levels, support for ‘Digital Cinema tremors by using an iPhone touchscreen, Package’ and support for interactive Blu-Ray menus too. If you are vocal trembling by using the microphone feeling bored, you can also play with its three new video filters: ‘old and also walking balance. movie’, ‘VHS effect’ and ‘freeze effect’. The ResearchKit framework is VLC 2.2 can be downloaded and used for free on Windows, Mac, Linux expected to help several problems faced and other mobile platforms including Windows Phones, Android and iOS. during medical research, and the apps Ubuntu users can also upgrade or install it through the official VLC Personal are built to be quite interactive too. The Package Archives. other apps mentioned include a diabetes diagnostic app from Massachusetts Mozilla Firefox 64-bit developer edition General Hospital, a heart disease launched for Windows diagnostic app from Stanford and the University of Oxford, an asthma health Mozilla recently launched Firefox 36 for desktops and Android devices. app from Mount Sinai Hospital and Weill And the 10th Firefox Cornell Medical College, and an app to anniversary was help victims of breast cancer, made by celebrated by launching the Dana-Farber Cancer Institute, UCLA the 64-bit Firefox School of Public Health, Penn Medicine Developer Edition 38 and Sage Bionetworks. Williams also said for Windows. that sensitive data will be visible only to medical researchers and that, “Apple will The version can be not see your data.” downloaded now from the Firefox Developer Edition page. The new version for Windows can run larger applications faster and it maintains a high security standard too. The browser is limited to 4GB of address space. In its blog post, Mozilla said that heap sizes in www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 13

FOSSBYTES Mozilla Firefox 36 to 32-bit browsers are recommended to be 512MB and this can reach up to 2GB in support the HTTP/2 the 64-bit browser. protocol The post, which refers to a game built by Epic Games’ Unreal Engine, adds, Mozilla has decided to support the “For some of the largest of these apps, a 64-bit browser means the difference HTTP/2 protocol in its upcoming between whether or not a game will run.” Mozilla launched Firefox Developer Firefox 36.0. The technology has Edition in November last year, and the company has offered 64-bit versions of been finalised as the next-generation Firefox for Mac OS X and Linux since a long time. But it’s only now that it’s HTTP (Hypertext Transfer Protocol) introduced this on the Windows platform too. network protocol. The Internet will adopt the new protocol in the near Firefox 36 for Android has also included HTTP/2 support, just like its future. Mozilla had proposed to desktop counterpart. With the new protocol, pages can be loaded faster than use HTTP/2.0 in upcoming Firefox before and the connections are longer lived too. The user interface is also releases a few weeks ago. The completely revamped and more features are expected to be added in future. decision was finalised on February 17. Firefox 36 for Android tablets has also added a full screen tab panel and a new search system. The new Android version also introduces the Maithili OpenLiteSpeed Web server has locale for Android Lollipop users, a number of changes in HTML codes for decided to support HTTP/2 draft developers and several fixes in VPNs. 16. Even Microsoft IIS Web server will support the HTTP/2 protocol in Arch Linux 2015.03.01 released with Linux kernel 3.18.6 upcoming Windows 10 OS. We can expect more and more technologies A brand new ISO image has been released for the lightweight, highly to adopt the HTTP/2 protocol in the customisable and powerful Arch Linux computer operating system. The new coming months. release is meant for those who want to deploy the acclaimed Mozilla Firefox 36.0 adds many distro on new computers. innovative features to the browser like the pinned tiles sync function. In the Arch Linux distro, The native HTML5 YouTube on the first day of each month, playback will be a much appreciated a new ISO image is released feature in the new browser. A newly and March 1 was no exception. A new ISO image includes all the updates released designed Preferences interface is during the previous month, including the core of the OS, the Linux kernel. enabled in the new browser. The flash protected-mode sandbox is disabled Arch Linux 2015.03.01 is powered by Linux kernel 3.18.6, and it includes on Windows to evaluate the stability all the updates that were released on the software repository of the distribution impact of protected mode. throughout February 2015. It also includes all the improvements, new packages and bug fixes. Firefox will no longer accept the insecure RC4 ciphers, If you are already using Arch Linux, then you don’t need to download whenever possible. The support for the new ISO image to keep your system updated as Arch Linux is a rolling- ECMAScript 6 symbol data type release distribution. The latest version can be installed on both 64- and 32-bit has been added to the new version. computer systems. Mozilla has implemented Unicode range CSS descriptor in the new LibreOffice 4.4.1 released with more than 100 fixes browser version. Users can create a new stacking context to isolate groups The Document Foundation has of boxes, to control which to blend announced the first maintenance together in Firefox 36.0. You can release of the stable LibreOffice expect more privacy features in this 4.4, which is an open source version of Firefox than ever before. and multi-platform suite. The new updated release is available for download too. LibreOffice 4.4.1 introduces some minor fixes so that the office suite stays stable The major addition of full support and dependable on all platforms. for HTTP/2.0 protocol enables a faster, more capable and more According to the official announcement, LibreOffice 4.4.1 fixes more than 100 responsible Web browsing experience. bugs, which were discovered by developers as well as users in the previous release, LibreOffice 4.4 ‘Fresh’. This was announced at the end of January 2015, and it was said to be the most beautiful LibreOffice ever. KDE Plasma gets a new update with version 5.2.1 Plasma is the desktop for the KDE project and it has got a new update now with 14 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

FOSSBYTES version 5.2.1. It’s a maintenance update that comes with some minor changes and improvements Plasma is the most noticed and talked about component of the KDE project. All the changes made to Plasma can be noticed immediately, though developers still need to make some more fixes. As mentioned in the official announcement, “Today KDE releases a bug fix update to Plasma 5, versioned 5.2.1. Plasma 5.2 was released in January with many feature refinements and new modules to complete the desktop experience. This release adds a month’s worth of new translations and fixes from KDE’s contributors.” The developers have explained that when videos are being watched in a Web browser, the screen or the suspend function will no more interrupt, Powerdevil will not use the entire CPU any more, and a crash that happened while switching to and from the Breeze widget style has been fixed too. Android Ice Cream Sandwich will not get any major Chrome release Android has moved way ahead from the era of Ice Cream Sandwich, and so has Google. The Android OS and Chrome browser maker has announced that it will not provide any major Chrome browser release for Android 4.0 (Ice Cream Sandwich). After the last major version of Chrome browser for Android KitKat, which is Chrome version 42, Google will freeze the development of the browser for the Android version. Google stated that the number of Chrome users on Android 4.0 have been decreasing constantly. In addition, the backward compatibility has been restricting the company from coming up with new features that will work well on older devices. Aurimas Lutikas, software engineer, Google, wrote in a blog post, “In the last year, we’ve seen the number of Chrome users running ICS drop by 30 per cent. Developing new features on older phones has become increasingly challenging, and supporting ICS takes time away from building new experiences on the devices owned by the vast majority of our users.” However, the company has promised regular security patches till Google releases version 43 of the Chrome browser. But the Ice Cream Sandwich users will not get anything after that from the Chrome development team. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 15

CSPOODRET Sandya Mannarswamy In this month’s column, we feature a list of interview questions on operating systems, algorithms and computer architecture. Over the past few months, we have been creating such a system? discussing natural language processing and 7. We all know that databases support ACID insight-centric storage systems. This month, we take a break from that discussion to explore a semantics where the ‘A’ in ACID stands for bunch of computer science interview questions. Let us atomicity. Atomicity means that either the start off on a light-hearted note. transaction completes successfully in its 1. What is the KISS Principle in computer science? entirety or it appears not to have started at all. 2. File systems and database systems both act as For example, consider the simple example of transferring money from your account to your containers of user data, albeit in different ways. Can father’s account. Successful completion means you differentiate the two in terms of the consistency that the money is debited from your account and guarantees they provide to the end user? credited to your father’s account. So if there is 3. Consider a file ‘1.txt’ on the same file system, say a failure while the transaction is in progress, ext4, on Linux, which is opened by two different say after the money has been debited from your processes. Both these processes modify overlapping account but before it is credited to your father’s regions of the file and close their individual file account, then the transaction is aborted and the handles. While each process has its own file handle effect to the end user is as if the transaction never on which it operates, how many file descriptors are started at all. This means that it appears as if the actually created for this file in the file system in the money was never debited from your account. Can kernel? If both process1 and process2 write ‘a’ and you explain the mechanism by which databases ‘b’ as the value at logical offset ‘0’ of the file ‘1.txt’, support such failure atomicity? Think of how what would actually be stored when these processes it would be possible to roll back a partially close their descriptive handles? completed transaction. 4. When the user invokes ‘ls’ on the root directory 8. What is a gossip protocol? How would you of your file system, can you explain what Linux implement it in a local network of computers? system calls get invoked internally? 9. The conventional wisdom with regard to traditional 5. What is a FUSE file system? How is it different storage media is that interrupt based signalling from a kernel level file system module? Can you of IO completion is more efficient than polling. reimplement the Linux ext4 file system as a FUSE Can you think of a situation where polling may module? If not, why not? be better than interrupt based IO completion 6. Instead of having local storage on a hard disk signalling? There is an interesting research paper connected to the device, you are asked to design which discusses this issue in detail, available at a file system which will store its data on a public https://www.usenix.org/legacy/events/fast/tech/ cloud storage provider like Amazon S3, which full_papers/Yang.pdf has an object interface. The file system needs 10. What are content addressable memories as opposed to provide normal file access semantics to local to traditional random access memories? applications, but has to store its durable data in the 11. You are asked to write a program which supports cloud. What are the design considerations when the following operations: 16 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

(a) Encrypts the input data and stores it as a file Guest Column CodeSport (b) Decrypts the data it reads from a file and displays it Can you write a small code snippet to do the same? week. You are asked to write a program to: If you are told that your program will execute on a a. Find the time when the number of users that were processor, which supports AES-NI instructions, how will you modify your code to take advantage of this logged into the computer was the maximum functionality? b. Find the time when the number of users that were 12. Given an array of N integers and a number ‘k’, write a function which returns true if the array has a logged into the computer was the minimum contiguous sub-sequence, which sums up to exactly c. Find the user who was online for the maximum ‘k’? How would your code change if you are asked to return the start and end of the contiguous sub- cumulative time over the one week sequence, if such a sub-sequence exists in the array. d. Find the user who was online for the longest single What is the time complexity of your solution? 13. You are given an array of N integers and asked to duration slot over that week return a popular item in the array, if such a popular What is the data structure you would use to item exists in the array. A popular item is an element represent the login, logout time intervals? which repeats at least N/4 times in the array. How 19. A string is said to be unique if no two characters would you modify your code if you are asked to return in the given string are identical. Given a set of N all such popular elements? What is the time and space strings, you are asked to find all unique strings complexity of your solution? present in the set. 14. You are given an array of N integers and asked to 20. Given a string, find all the sub-strings of that string write a program to find the maximum difference which are palindromes. between two array elements A[i] and A[j] such that i 21. You are given two binary trees and asked to determine < j. How would your solution change if the condition whether the two trees are identical both in terms of that ‘i’ needs to be smaller than ‘j’ need not hold true structure and the elements contained in them. Write for your program? a program to do this. What is the time and space 15. You are given an array of N elements, where each complexity of your solution? How would your code element is a task. Each task has a priority, which is change if you are told that the binary trees are actually marked as either High, Medium or Low. You are asked binary search trees? to rearrange the array such that all tasks which have 22. If you are asked to write a sort routine to replace the the priority value ‘High’ appear first, followed by tasks sort utility in UNIX/Linux, which sorting algorithm whose priority is ‘Medium’, and then by tasks whose would you use and why? priority is ‘Low’. You are asked to do this in-place 23. If you are asked to design a data structure which needs with constant additional storage. What is the time to support (a) insert, (b) delete, (c) search, (d) find- complexity of your solution? minimum, and (e) find-maximum, which data structure 16. You are given a text file, which contains C/C++ would you use and why? code. The code has comments in it. The comments 24. What is a lock-free data structure? Can you give an can be either single line or multi-line. Single example of one? line comments begin with a ‘//’ character and do 25. The two terms ‘concurrency’ and ‘parallelism’ not span beyond a line. Multi-line comments are are often mistaken for each other in computer enclosed by ‘/*’ and ‘*/’ characters. Comments science. Can you differentiate between the two with cannot nest inside each other. You are asked to write appropriate examples of where concurrency exists a code snippet which strips out the comments from and where parallelism does? the code in the input file. If you have any favourite programming questions 17. You are given a binary search tree containing N or software topics that you would like to discuss on this integers. You are asked to return the ‘kth’ largest forum, please send them to me, along with your solutions element in the binary search tree. Write a code snippet and feedback, at sandyasm_AT_yahoo_DOT_com. Till we to do this. How would your solution change if you are meet again next month, happy programming! asked to return the ‘largest’ element and the ‘smallest’ element in the binary search tree? What is the time and By: Sandya Mannarswamy space complexity of your solution? 18. You are given a list of N users along with their login The author is an expert in systems software and is currently working and logout times on the computer, over a period of one with Hewlett Packard India Ltd. Her interests include compilers, multi-core and storage systems. If you are preparing for systems software interviews, you may find it useful to visit Sandya’s LinkedIn group, Computer Science Interview Training India at http://www. linkedin.com/groups?home=HYPERLINK “http://www.linkedin.com/ groups?home=&gid=2339182”&HYPERLINK “http://www.linkedin. com/groups?home=&gid=2339182”gid=2339182 www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 17

Exploring Software Guest Column Spark: Exploring Big Data Anil Seth on a Desktop Here’s an introduction to Apache Spark, a very fast tool for large scale data processing. Spark is easy to use, and runs on Hadoop and Mesos as a standalone application or on the cloud. Applications can be quickly written in Java, Scala or Python. Developers boast that it can run programs 100 times faster than MapReduce in memory, or 10 times faster on disk. My interest in Hadoop had been sparked a year >>> result = data.flatMap(lambda line:re.sub('[^a-z0-9]+',' ago by the following headline: “Up to 100x ',line.lower()).split()) faster than Hadoop MapReduce.” Now, it’s finally time to explore Apache Spark. .map(lambda x:(x,1)) .reduceByKey(lambda a,b:a+b) MapReduce expects you to write two programs, a >>> output=result.collect() mapper and a reducer. The MapReduce system will try >>> output.sort() to run the mapper programs on nodes close to the data. >>> for w,c in output: The output of various mapper programs will be key value >>> print('%s %d'%(w,c)) pairs. The MapReduce system will forward the output to various reducer programs, based on the key. The shell creates a Spark context, sc. Use it to open the files contained in the HDFS docs directory for the In the Spark environment, you write only one set user Fedora. of code containing both the mapper and reducer code. The framework will distribute and execute the code in You use flatMap to split each line into words. In this case, a manner that will try to optimise the performance and you have converted each line into lower case and replaced all minimise the movement of data over the network. Besides, non-alphanumeric characters by spaces, before splitting it into the program could include additional mappers and words. Next, map each word into a pair (word, 1). reducers to process the intermediate results. The mapping is now complete and you can reduce it Installing Spark by keyword, accumulating the count of each word. So far, the response would have been very fast. Spark is lazy and You will need to download the code from the Apache evaluates only when needed, which will be done when you Spark site (http://spark.apache.org/) based on the version run the collect function. It will return a list of word count of Hadoop on your system. Installation involves just pairs, which you may sort and print. unzipping the downloaded file. The documentation will guide you on how to configure it for a cluster, e.g., Finding out which files contain a particular word consisting of three nodes – h-mstr, h-slv1 and h-slv2. Let’s assume that you have a large number of small text files Getting a taste of Spark with word count and you would like to know how frequently a particular word occurs in various files. Let’s suppose that you have already created and copied text files in the Hadoop Distributed File System (HDFS) in Spark has the option to process the whole file rather than the directory /user/fedora/docs/. one record at a time. Each file is treated as a pair of values – the file name and the content. Start the Python Spark shell, as follows: from pyspark import SparkContext $ bin/pyspark import re # input to wholeFile is a file name, file content pair Open the text files in HDFS and run the usual word def wholeFile(x): count example: name=x[0] >>> data = sc.textFile('hdfs://h_mstr/user/fedora/docs') words = re.sub('[^a-z0-9]+',' ',x[1].lower()).split() return [(word,name) for word in set(words)] 18 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

Guest Column Exploring Software sc = SparkContext(appName='WordsInFiles') and the filter method in the class can use this list. data = sc.wholeTextFiles('hdfs://h_mstr/user/fedora/docs') The next step is like the word count example. Each word_index = data.flatMap(wholeFile).reduceByKey(lambda a,b:','.join((a,b))) line is a word followed by a string of comma-separated word_index.persist() file names. So, split the file names into a list and count output=word_index.collect() the number of times each file is selected. output.sort() # print the first 10 values Sort the results in descending order (of the frequency) for i in range(10): and print them. You can repeat the exercise for various keywords and the intermediate data set will be reused print output[i] without the need to save it in a file. This is one of the explore(word_index) major advantages of Spark over MapReduce. sc.stop() From a developer’s perspective, the ability to The function wholeFile returns a list of (word, file code the entire analysis (which may consist of a name) pairs for unique words. As earlier, the text has sequence of MapReduce operations) in a single file been converted to lower case and all special characters makes it much easier to think through the problem replaced by a space. and write better code. The reduceByKey function joins all the file names with a By: Dr Anil Seth comma as the separator. For verification, the first 10 results of the sorted output are printed. The author has earned the right to do what interests him. You can find him online at http://sethanil.com and http://sethanil.blogspot. The persist method saves the result of word_index, com, or reach him via email at [email protected]. which is useful if you want to use the same data set again. For example, in the explore method mentioned above, you DEMEBVEDEDLEOD SPOMFTEWNARTE may want to analyse a list of words and see how many of these words appear in a file. COURSES AND WORKSHOPS class filter_keys(): School of Embedded Software def __init__(self,keys): self.keys = keys www.schoolofembedded.org def filter(self,x): return x[0] in self.keys COURSES: • Embedded System Programming on Arm-Cortex-M def explore_keys(rdd,keys): • ARM Cortex-M architecture, internals and Programming example = filter_keys(keys) • Embedded OS internals and programming res = rdd.filter(example.filter) \\ • BSP and drivers .flatMap(lambda x:x[1].split(',')) \\ • Linux Internals for Driver Development - in April 2015 .map(lambda x:(x,1)) \\ • Linux Device Drivers .reduceByKey(lambda a,b:a+b) VENUE: out=res.collect() School of Embedded Software Development out.sort(lambda a,b:-a[1].__cmp__(b[1])) Kalyan Nagar, HRBR Layout, Bangalore - 560043 print keys,len(out) Faculty : Babu Krishnamurthy print out Email : [email protected] Phone : +91-98453-65845/080-41207855 def explore(rdd): COURSE DETAILS: explore_keys(rdd,['linux','fedora','ubuntu']) http://www.schoolofembedded.org/course_s explore_keys(rdd,['linux','fedora','ubuntu','python']) http://www.schoolofembedded.org/events-default The first step is to select only those records that pertain to the keywords. The Filter operation on the data set will do just that. However, we need to pass a list of words as a parameter and this can be achieved by creating the class filter_keys. The class is initialised with a list of keywords www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 19

Developers How To Talking to the Kernel through Sysfs The Linux kernel provides a virtual file system called sysfs. By providing virtual files, sysfs is able to export information about various kernel sub-systems, hardware devices and associated device drivers from the kernel’s device model to user space. To further explore sysfs, dive deep into this article. There is a need to provide information related to each RAM based file system. It is designed to export the kernel process, to the user space, which can then be used data structures and their attributes from the kernel to the user by programs such as ps. The /proc file system was space, which then avoids cluttering the /proc file system. created for this purpose. Through the proc file system, each process has its directory in the /proc folder. It was originally The advantages of sysfs over procfs are as follows: designed to provide process related information to user space. ƒ A cleaner, well-documented programming interface Adding directories and files to the /proc file system is easier; ƒ Automatic clean-up of directories and files, when the so, many kernel sub-systems started using this file system for displaying information to the user space. It is also used to take device is removed from the system inputs from the user space to control settings inside the kernel ƒ The enforced one item per file rule, which makes for a modules. But the /proc file system is getting cluttered with lots of non-process related information. cleaner user interface The ‘one item per file’ rule mandates that in each file of From the Linux 2.5 development cycle, a new interface sysfs, there will be only one value that can be put in or read called the /sys file system has been introduced. Sysfs is a from it. This feature really makes it a cleaner interface. Through sysfs, user space programs can get information from the kernel sub-system like device drivers. Programs 20 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers can also send values to the kernel sub-system and can sysfs, the struct kobject pointer that is passed to sysfs_create_ control the internal settings. This is how programs talk to dir should have the parent kobject pointer pointing to the the Linux kernel. kobject of the directory in which the current directory is to be created. Then the name parameter of the kobject should be Sysfs mounting filled, with the proper name representing the functionality for which the directory is being created. By default, sysfs is compiled in the Linux kernel. It is dependent on CONFIG_SYSFS being enabled in the kernel But the above interfaces are not directly used to create configuration. If sysfs is not already mounted, then you can do directories in sysfs when writing kernel modules; instead, the so by using the following command: following interface is used: mount -t sysfs sysfs /sys struct kobject * kobject_create_and_add(const char *name, struct kobject *parent); Linux Kernel objects …where, Folders in each sysfs directory are represented by kernel name: is the name of the directory to be created in sysfs, objects (kobjects) in Linux. These are represented in the and… kernel through the struct kobject (defined in include/linux/ parent: is the kobject of the parent directory in which the kobject.h). The important members of the struct kobject are current directory is to be created. given below. The return value of the kobject_create_and_add is the kobject pointer of the created directory, and if it fails to create char *name: This is the name of the kobject. Folders a directory then a NULL pointer is returned. corresponding to the current kobject are created with this Kobject parent pointer: Since each folder in the name in sysfs. sysfs file system is represented using a struct kobject, to create a new directory in sysfs, the parent pointer is to be Struct kobject *parent: This is the parent of the current initialised with the kobject of the directory in which the kobject being created. When a folder is created in sysfs, if current directory is to be created. For example, to create a this field is present, then the current kobject folder is created directory named example_dev in /sys/kernel, the following inside the parent kobject folder. function call is used: Struct kref: This is the reference counting mechanism for struct kobject *example_dev_kob; kobject. Whenever any kernel module refers to any kobject, its reference count is incremented, and whenever any kobject example_dev_kobj = kobject_create_and_add(“example_dev”, reference is released by any kernel module, then the reference kernel_kobj); count is decremented. When the reference count decrements to zero, memory related to the kobject is released. …where, kernel_kobj is the kobject pointer of the kernel directory in sysfs. So in order to create a directory in /sys/ Directory operations in sysfs firmware, the firmware_kobj pointer will be used. The following are the interfaces that are used for directory In order to create the directory named example_dev related operations in sysfs: directly in /sys, the following function call is used: int sysfs_create_dir(struct kobject *kobj); kobject_create_and_add(“example_dev”, NULL); void sysfs_remove_dir(struct kobject *kobj); int sysfs_rename_dir(struct kobject *kobj. const char *new_ …so if the parent pointer is kept NULL, then the name); example_dev directory will be created in the /sys folder. Sysfs directory creation Sysfs directory removal The sysfs_create_dir interface is used to create a directory in The sysfs_remove_dir interface is used to remove the sysfs. The struct kobject parameter passed to it has two fields directory from the sysfs file system. The parameter that is in it. passed to the sysfs_remove_dir is the kobject pointer of the directory which is to be removed. The kobject pointer should kobj->name: This is the name of the directory that is to be be used to create the directory. Here, too, the same concept created in sysfs. applies. Instead of directly calling this interface to remove the directory, the following kernel kobject interface is used, kobj->parent: This is the kobject pointer of the parent which internally calls the sysfs remove interface: directory in which the current directory is to be created. Since each directory in sysfs has a struct kobject associated with it, when the new directory is to be created in www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 21

Developers How To void kobject_del(struct kobject *kobj); kobject_get increments the reference count of the kobject passed to it, whereas kobject_put decrements the reference This interface will delete the directory of sysfs count of the kobject passed to it. So while writing drivers or any kernel module, whenever any kobject of the other module represented by the kobject pointer passed to it. is directly used, kobject_get should be called to increment the For example, to delete the example_dev directory that was reference count of the kobject. When the use of the kobject is finished, kobject_put should be called to decrement its created as an example, the following function call is used: reference count. kobject_del(example_dev_kobj); Whenever kobject_put is called, passing the kobject pointer to it, it decrements the reference count. When the Sysfs directory renaming reference count reaches zero, it frees the memory of the kobject pointer, and the kobject pointer can no longer be used. In case there is a need to rename the directory created in sysfs, the following functions are available: int sysfs_rename_dir(struct kobject *kobj, const char *new_ Files in sysfs name) In the above example, we have created the example_dev …where, kobj is the kobject pointer corresponding to the directory in the /sys/kernel folder. Suppose the example had directory that has to be renamed, and some attribute called example_info which we want to expose to the user space using sysfs, then the feature used is called new_name is to be given to the directory. Since the sysfs sysfs attributes. interface is normally not directly called, the following kobject interface is called for the renaming purpose: Attributes are represented as regular files in sysfs with one value per file. Attributes are of the type struct attribute int kobject_rename(struct kobject *kobj, const char *new_ (defined in include/linux/sysfs.h). Struct attribute has the name) following two important pieces of information. …where, name: This is the name of the attribute(file) to be created. kobject: This is the kobject pointer of the directory to be mode: This is the permission with which the file is to be renamed. created. A simple attribute has no means by which it can be new_name: This is the new name to be given to the read or written; it needs wrapper routines for reading and directory. writing. For this purpose, kobject defines a special structure called struct kobj_attribute (defined in include/linux/ kobject.h) as follows: Kobject reference counting struct kobj_attribute { Each kobject has a member struct kref, which is a reference struct attribute attr; counter. Whenever any module wishes to use the kobject already created, this reference count is incremented, and ssize_t (*show)(struct kobject *kobj, struct kobj_attribute whenever that module wishes to stop using kobject, the *attr, char *buf); reference count is decremented to maintain the number of modules using the kobject or the sysfs directory represented ssize_t (*store)(struct kobject *kobj, struct kobj_ by the kobject. Whenever the reference count reaches 0, attribute *attr, const char *buf, size_t count); the memory related to the kobject which was allotted by }; kobject_create_and_add is released, and whenever a kobject is created using kobject_create_and_add, it internally …where, attr is the attribute representing the file to be initialises the kref reference counter by one. This indicates created, show is the pointer to the function that will be called the kobject is being used by the current module, and then when the file is read in sysfs, and store is the pointer to the kobject_create_and_add internally creates the directory for function which will be called when the file is written in sysfs. the kobject. Whenever any new module wishes to use the directory represented by that kobject, the reference counter Suppose we need to create our example_info file in the /sysfs/ has to be incremented. kernel/example_dev directory that was created as an example; then the following method is the way to define the attribute: The reference count is maintained in the kobject using the following functions: struct kobj_attribute example_info_attr = __ATTR(example_info, 0666, example_show, example_store); struct kobject* kobject_get(struct kobject *kobj); struct kobject* kobject_put(struct kobject *kobj); …where __ATTR is the macro, as shown below: 22 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers __ATTR(name, permission, show_ptr, store_ptr) which was passed when the file was created. attr: This is the attribute pointer of the file which was …where, name is the name with which the attribute is to be created, permission is file permission where 0666 is read passed when file was created. and write permission, show_ptr is the function pointer called buff: This is the buffer in which the output should be when the file is read, and store_ptr is the function pointer called when the file is written. written, which will be displayed as the result in user space. The value written should not exceed the size defined by the The example_attr defined above is then grouped in the PAGE_SIZE macro. struct attribute group as follows: ssize_t (*store)(struct kobject * kobj, struct attribute * struct attribute *example_attrs[] = { attr, const char * buff, size_t size); &example_attr.attr, NULL, …where, kobject and attr are as described above. }; buff: This buffer contains the value that was written to the file from user space. Note: In the struct attribute, multiple attributes can size: This is the size of the data written to the file through be grouped together and then be created in one single API user space. call. Also, NULL termination is compulsory for the group. So our example_show function can be defined as follows: The above attributes are then given to the attribute group ssize_t example_show(struct kobject *kobj, struct kobj_ as follows: attribute *attr, char *buf) { struct attribute_group example_attr_group = { .attrs = example_attrs, return sprintf(buf, “example show”); /*Here any value of variable can be written and exposed to }; user space through this interface also return value is the size of data written to the To create attributes, the following sysfs API is used: buffer*/ } int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); …and an example store can be written as follows: …where, static ssize_t example_store(struct kobject *kobj, struct kobj: This is the pointer to the kobject of the directory in kobj_attribute *attr, const char *buf, size_t count) which the file is to be created. { grp: This is the group of attributes to be created, which //here the value from the buff can be read and //respective will be created as files in sysfs. action can be taken by module To create the example_info file in our /sys/kernel/ example_dev directory, the following sysfs API is called: return count; sysfs_create_group(example_dev_kobj,&example_attr_group); //return the number of bytes read, if all the //bytes are read the count parameter which //was received by store After this function, a file named example_info will be routine created in the sys/kernel/example_dev directory. } Now, whenever the file is read, the example_show Driver sysfs interface function will be called and whenever the file is written, the example_store function will be called, which needs to Drivers are modules written to interface user space with be defined. The function prototype for the show and store hardware devices. Hardware devices have information, which the function is as follows: user needs to know during their operation. So drivers generally create sysfs files for providing their information to user space. ssize_t (*show)(struct kobject * kobj, struct attribute * attr, char * buff); Drivers don’t explicitly create directories in sysfs. Whenever drivers register with their sub-system, directories …where, are internally created for the driver. Each driver has access kobj: This is the pointer to the kobject of the directory to the struct device pointer for the device for which the driver is being written. This device pointer is used to create files in the driver interface. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 23

Developers How To Drivers create one file for each piece of device …where, information that is to be exposed to the user space through kobj: This is the pointer to the kobject that represents the sysfs. Drivers use a special API for file creation in the user directory in which the link is to be created. space, and this is as follows: target: This is the target directory to which the link is to be pointed. int device_create_file(struct device *dev, const struct name: This is the name with which the link is to be created. device_attribute *attr); For our example, the link is created as follows: …where, sysfs_create_link(ex1_kobj, ex2_kobj, “ex2”); dev: This is the pointer to the device structure of the driver module. To delete symbolic links, the following interface is available: attr: This is the attribute which is to be created. For removal of the file from the sysfs directory, the void sysfs_remove_link(struct kobject *kobj, char *name); following interface can be used: In our example, to delete the link, the following function void device_remove_file (struct device *dev, const struct is called: device_attribute *attr) sysfs_remove_link(ex2_kobj, “ex2”); Sysfs object relationship References Let’s suppose there is the directory /sys/kernel/example1, the kobject pointer of which is ex1_kobj and there is a need to [1] https://www.kernel.org/doc/Documentation/ create a link file in the /sys/kernel/example2 directory named filesystems/sysfs.txt ‘ex2’, which has to show the relationship with the example1 directory. This can be accomplished by symbolic links in sysfs. [2] http://lxr.missinglinkelectronics.com/linux/drivdri/ Also, the kobject pointer of the example2 directory is ex2_kobj. rtc/rtc-ds1343.c Symbolic links are created in sysfs through the following [3] https://www.kernel.org/pub/linux/kernel/pepepe/ interface: mochel/doc/papers/ols-2005/mochel.pdf int sysfs_create_link(struct kobject *kobj, struct kobject By: Raghavendra Chandra Ganiga *target, char *name); The author is an embedded firmware development engineer at K2 Technosoft Pvt Ltd, Pune. His interests are microcontrollers, networking firmware, RTOS development and Linux device drivers. You can contact him at [email protected] osFy Magazine Attractions during 2015-16 Month theMe buyers’ guide March 2015 April 2015 Open Source Firewall and Network security SSD for Servers May 2015 June 2015 Web Development Network Switches July 2015 August 2015 Virtualisation (containers) Wireless Routers for SME September 2015 October 2015 Open source Databases PaaS Solution November 2015 December 2015 Network Monitoring MFD Printers for SMEs January 2016 February 2016 Mobile App Development Hosting Solutions Backup and Data Storage External HDD Mobile App Development IaaS Solution Cloud Special Firewall and UTMs Open Source on Windows Online Backup solutions Android Special Wifi Hotspot Devices Top 10 of Everything External Storage 24 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Open Gurus Using Scilab with the McCabe-Thiele Method Cross-platform, open source numerical computational package, Scilab, can be used for image enhancement, fluid dynamics simulations and numerical optimisation, among other things.When used with the McCabe-Thiele method, which is said to be the simplest and perhaps most instructive method for the analysis of binary distillation, the combination is formidable. The McCabe-Thiele method was published 90 diagonal is called the azeotrope. At this point, the vapour phase years ago by Warren L. McCabe and Ernest W. has the same composition as the liquid phase and the mixture Thiele in an article titled ‘Graphical Design of cannot be separated by a simple distillation. The data points are Fractionating Columns’. To use their own words, “… now fitted with three different techniques to obtain the VLE the method consists essentially in drawing, on the same curve equation: rectangular plot, the equilibrium curve for vapour and ƒ Cubic spline monotone liquid compositions and straight lines representing the ƒ Rational function 1 (with four coefficients) equations for enrichment from plate to plate, and passing ƒ Rational function 2 (with six coefficients) from one to another in a series of steps.” Scilab is an open source software for numerical computation with a syntax // Rational function 1 similar to MathWorks’ MATLAB. The aim of this article is deff(“[y]=f(a,b,c,d,x)”,”y=((a+b*x)./(1+c*x+d*x.^2))”); to show how Scilab can be used to plot the McCabe-Thiele deff(“[e]=res(A,x,y)”,”e=f(A(1),A(2),A(3),A(4),x)-y”); diagram and simulate the distillation of a binary mixture. Ainit=[1;1;1;1]; All the Scilab examples presented here are made under [S,coe]=leastsq(list(res,x,y),Ainit); Linux Mint 17 Xfce. yp1=f(coe(1),coe(2),coe(3),coe(4),xx); The vapour-liquid equilibrium curve // Rational function 2 deff(“[y]=f(a,b,c,d,e,f,x)”,”y=((a+b*x+c*x.^2)./ First, it’s necessary to plot the vapour-liquid equilibrium (1+d*x+e*x.^2+f*x.^3))”); deff(“[e]=res(A,x,y)”,”e=f(A(1) (VLE) curve for the most volatile (lower-boiling) component ,A(2), A(3),A(4),A(5),A(6),x)-y”); in the mixture. For the two mixtures discussed here (ethanol/ Ainit=[1;1;1;1;1;1]; water and chloroform/methanol), the data points (x,y) are taken [S,coe]=leastsq(list(res,x,y),Ainit); from the third reference given at the end of this article. Note yp2=f(coe(1),coe(2),coe(3),coe(4),coe(5),coe(6),xx); that the point at which the VLE curve cuts the diagram on the www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 25

Open Gurus How To and fourth references at the end of this article. Then it’s possible to draw another line called the operating line for the enriching section (the section above the feed inlet, the yellow line in Figures 4 and 5). This second line starts on the diagonal at the xD value and cuts the y-axis at the value xD/(R+1). The last line is called the operating line for the exhausting section (the section below the feed inlet, the magenta line in Figures 4 and 5). This third line starts on the diagonal at the xB value and ends at the intersection (xi,yi) of the two previous lines. xF=0.35; // Feed mole fraction xD=0.6; // Distillate mole fraction xB=0.05; // Bottom product mole fraction R=1.5; // Reflux ratio R=L/D q=1; // Feed thermal conditions Figure 1: The VLE curve for the ethanol/water mixture xi=(-(q-1)*(1-R/(R+1))*xD-xF)/((q-1)*R/(R+1)-q); // Figure 2: The VLE curve for the chloroform/methanol mixture Intersection x point // Cubic spline monotone df=splin(x,y,”monotone”); yi=(xF+xD*q/R)/(1+q/R); // [yyf,yy1f,yy2f]=interp(xx,x,y,df); plot([0,1],[0,1],”c-”,.. // Diagonal Intersection y point xx,yp1,”b-.”,.. // Rational function 1 plot([0,1],[0,1],”c-”,.. // Diagonal xx,yp2,”g-”,.. // Rational function 2 xx,yyf,”k-.”,.. // Cubic spline monotone xx,yp,”k-”,.. // Rational function 2 x,y,”ko”); // Data points [xF,xi],[xF,yi],”k-”,.. // q-line The Rational function 2 was chosen as the most [xD,xi],[xD,yi],”y-”,.. // Operating line enriching section interesting (see the green curve in Figures 1 and 2) and six coefficients will be used to define each VLE curve. A simple [xB,xi],[xB,yi],”m-”); // Operating line exhausting section polynomial model was not chosen because of its instability. Finally, it’s possible to draw the steps between the The McCabe-Thiele method operating lines and the VLE curve and then count them (Figures 4 and 5). These steps represent the equilibrium The next step is to draw the q-line. This line starts on the diagonal stages (theoretical plates) required to carry out the distillation at the xF value and has a slope which depends on the feed thermal at the given conditions. The required number of theoretical conditions. In Figures 4 and 5, because we have a saturated-liquid plates is seven for the example in Figure 4, and six for feed, the q-line is vertical. For the other q-line types, see the third the example in Figure 5. The Scilab code used to plot the operating lines and the equilibrium stages is adapted to Scilab from the MATLAB code written by Housam Binous, as reported in the fifth reference at the end of this article. // VLE curve equation function f=equilib(x) f=y-((coe(1)+coe(2)*x+coe(3)*x.^2)./(1+coe(4)*x+coe(5)*x. ^2+coe(6)*x.^3)); endfunction // Enriching section i=1; xp(1)=xD; yp(1)=xD; y=xD; while (xp(i)>xi), xp(i+1)=fsolve(0.01,equilib); // Steps x coordinates yp(i+1)=R/(R+1)*xp(i+1)+xD/(R+1); // Steps y coordinates y=yp(i+1); plot([xp(i),xp(i+1)],[yp(i),yp(i)],”r-”); // Steps plot if (xp(i+1)>xi) then plot([xp(i+1),xp(i+1)],[yp(i),yp(i+1)],”r-”); // 26 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Open Gurus Figure 3: Very simplified schema for a generic distillation process Figure 5: Distillation of the chloroform/methanol mixture Figure 4: Distillation of the ethanol/water mixture Figures Notes Vertical lines 1 Reference 3 at the end of the article does not end give the data beyond the azeotrope. i=i+1; end 3 F, feed; L, liquid; D, distillate; R=L/D, reflux // Exhausting section ratio; B, bottom product; C, distillation column; SS=(yi-xB)/(xi-xB); E1, condenser; E2, reboiler. yp(i)=SS*(xp(i)-xB)+xB; y=yp(i); 4 xF (feed composition)=0.4; xD (distillate com- plot([xp(i),xp(i)],[yp(i-1),yp(i)],”g-”); // Vertical line position)=0.75; xB (bottom product composi- while (xp(i)>xB), tion)=0.05; R=1.5; q=1. xp(i+1)=fsolve(0.01,equilib); // Steps x coordinates yp(i+1)=SS*(xp(i+1)-xB)+xB; // Steps y coordinates 5 xF=0.35; xD=0.6; xB=0.05; R=1.5; q=1. y=yp(i+1); plot([xp(i),xp(i+1)],[yp(i),yp(i)],”b-”); // Steps plot With Scilab, it’s possible to calculate the equation if (xp(i+1)>xB) then of a vapour-liquid equilibrium curve with the use of a rational function, at least as a first guess. Probably, in plot([xp(i+1),xp(i+1)],[yp(i),yp(i+1)],”b-”); // the future, it will be necessary to improve this kind of Vertical lines rational function. Then it will be possible to simulate a distillation process to obtain the number of equilibrium end stages. I hope this article will stimulate the reader’s i=i+1; curiosity about Scilab. end References [1] McCabe, Thiele, Graphical Design of Fractionating Columns, Industrial and Engineering Chemistry, 1925, 17 (6), 605-611 [2] http://www.scilab.org, last visited on 26/12/2014 [3] Perry, Green, Maloney (editors), Perry’s Chemical Engineers Handbook, 7th edition, McGraw-Hill, New York, 1997 [4] Foust, Wenzel, Clump, Maus, Andersen, I principi delle operazioni unitarie (Principles of Unit Operations), Casa Editrice Ambrosiana, Milan, 1967 [5] http://www.mathworks.com/matlabcentral/fileexchange/ 4472-mccabe-thiele-method-for-an-ideal-binary-mixture, last visited on 26/12/2014. By: Stefano Rizzi The author works in the analytical chemistry and textile chemistry areas. He has been a Linux user since 1998. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 27





Developers How To How to Install Moodle on a LAMP Server Moodle, the free and open source learning platform, can be used to create private websites for dynamic online courses. Moodle can be used in the academic as well as corporate world for e-learning projects. So let’s find out how to install it. Moodle is an open source learning management (e.g., /var/www/html/moodle). system (LMS) that can be used for academic as 3. Also create an empty directory with the name well as administrative tasks. It was founded by Martin Dougiamas and is an acronym for Modular Object ‘moodledata’ in the directory, one level above the Oriented Dynamic Learning Environment. This LMS acts document root (e.g., /var/www/moodledata). as a powerful teaching-learning tool as it comes bundled 4. Set the permissions of Moodle and ‘moodledata’ as with many features that can be used by teachers, students or follows: administrative staff. In this article, we explore how to install Moodle on a LAMP server. chmod -R 777 /var/www/html/moodle chmod -R 777 /var/www/moodledata The operating system used here is Linux Mint 17.1 ‘Rebecca’. The permissions are set to 777 so that the installation script can read/write contents from and to the files in the directories. The prerequisites for Moodle version 2.8 (the latest) are: 5. Create an empty directory using phpMyAdmin or the ƒ PHP 5.4.4 ƒ MySQL 5.5.31 mySQL console. To use phpMyAdmin, type localhost/ ƒ Mozilla Firefox 25.0 phpmyadmin in the browser’s address bar. Log on, and ƒ Apache 2, to host the site select the Databases tab. Enter the name of the database and click on the Create button. The following steps will help you install Moodle on your 6. In a new tab in the browser, type localhost/moodle to begin server in no time. the installation process. 1. Download a stable version of Moodle from https:// 7. Select the language and click on Next. The default language is English. download.moodle.org/releases/latest. 2. Extract the directory in the document root of the server 30 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers Figure 3: Front page setting Figure 4: Manage authentication Figure 1: Moodle installation Figure 5: Server checks php.ini file Figure 2: Server check page Figure 4: Step 11 a 8. Enter the path of the data directory, that is, the moodledata Figure 5: Step 11 b directory (/var/www/moodledata). 12. The plugins being 9. Select Improved MySQL as the database driver and click installed will be displayed. Click on Continue after all the on Next. plugins have been installed. 10. Read the copyright notice and click on Continue. 13. Enter the details of the 11. In the Server checks page, if the status of any PHP admin user. Then click on Update profile. extension is ‘Not OK’, enable the appropriate PHP 14. Enter the site name and extension. The configuration for PHP can be found in the other details, and click on php.ini file (/etc/php5/apache2/php.ini). Click on Continue. Save changes. Moodle has been installed successfully. You can now create categories and courses on the site. Moodle comes with a set of default features such as assignments, files, forums, quizzes. To add more features, you can download plugins from https://moodle. org/plugins/ and install them on your site. References [1] https://docs.moodle.org/25/en/History [2] https://docs.moodle.org/dev/Moodle_2.8_release_notes By: Gayatri Venugopal The author is assistant professor at Symbiosis Institute of Computer Studies and Research (SICSR), Pune, and is involved in the development and maintenance of Moodle at SICSR. She can be contacted at [email protected]. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 31

Developers How To Access Redis and PostgreSQL Databases with Haskell Named after logician Haskell Curry, Haskell is a standardised,general-purpose, purely functional programming language, with non-strict semantics and strong static typing.This tenth article on Haskell explores access to Redis and PostgreSQL databases using Haskell modules. The Hackage website at https://hackage.haskell.org/ $ cabal install hedis packages/#cat:Database provides a vast number of database packages that you can use, a couple of which This installs the latest hedis version 0.6.5. You can now will be covered here. start the Redis server on Fedora using the service command: You will need to install the cabal-install tool on Fedora, for example, using the following command: $ sudo service redis start $ sudo yum install cabal-install You can then test connectivity to the Redis server using the redis-cli command by issuing the PING command as Connecting to the Redis database follows: Let’s use the hedis package to connect to the Redis server. $ redis-cli Install the Fedora dependency package alex, and the Redis server as shown below: 127.0.0.1:6379> PING PONG $ sudo yum install alex redis You can then install the hedis package using the following You can also test the same using the hedis package inside commands: the GHCi interpreter as illustrated below: $ cabal update $ ghci 32 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help ghci> :t conn Loading package ghc-prim ... linking ... done. conn :: Connection Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. ghci> :t connect connect :: ConnectInfo -> IO Connection ghci> :m Database.Redis ghci> :t runRedis ghci> conn <- connect defaultConnectInfo runRedis :: Connection -> Redis a -> IO a Loading package array-0.4.0.1 ... linking ... done. ghci> :t ping Loading package base-unicode-symbols-0.2.2.4 ... linking ... done. ping :: RedisCtx m f => m (f Status) Loading package deepseq-1.3.0.1 ... linking ... done. Loading package old-locale-1.0.0.5 ... linking ... done. If the Redis server was not started, and you tried to Loading package time-1.4.0.1 ... linking ... done. issue the ping command, the following exception would be Loading package transformers-0.3.0.0 ... linking ... done. automatically thrown by the package: Loading package bytestring-0.10.0.2 ... linking ... done. Loading package text-0.11.3.1 ... linking ... done. ghci> runRedis conn ping Loading package stm-2.4.2 ... linking ... done. *** Exception: connect: does not exist (No route to host) Loading package primitive-0.5.0.1 ... linking ... done. Loading package vector-0.10.0.1 ... linking ... done. You can automate the above code snippets into Haskell Loading package hashable-1.1.2.5 ... linking ... done. code with a main function, as demonstrated below: Loading package transformers-base-0.4.1 ... linking ... done. Loading package monad-control-0.3.2.1 ... linking ... done. {-# LANGUAGE OverloadedStrings #-} Loading package containers-0.5.0.0 ... linking ... done. import Database.Redis Loading package attoparsec-0.10.4.0 ... linking ... done. main :: IO (Either Reply Status) Loading package mtl-2.1.2 ... linking ... done. main = do Loading package BoundedChan-1.0.3.0 ... linking ... done. Loading package bytestring-lexing-0.4.3.2 ... linking ... done. conn <- connect defaultConnectInfo Loading package unix-2.6.0.1 ... linking ... done. runRedis conn ping Loading package network-2.6.0.2 ... linking ... done. Loading package resource-pool-0.2.3.2 ... linking ... done. The OverloadedStrings extension allows string literals to be Loading package hedis-0.6.5 ... linking ... done. polymorphic for the IsString class. You can compile and run the above code inside GHCi, as follows: ghci> runRedis conn ping $ ghci ping.hs Right Pong GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help I would recommend that you use defaultConnectInfo to connect to the database, and its type is ConnectInfo: Loading package ghc-prim ... linking ... done. ghci> :t defaultConnectInfo Loading package integer-gmp ... linking ... done. defaultConnectInfo :: ConnectInfo Loading package base ... linking ... done. [1 of 1] Compiling Main ( ping.hs, interpreted ) Ok, modules loaded: Main. The different options that can be used in defaultConnectInfo ghci> main are as follows: ... Right Pong connectHost = “localhost” The echo Redis command is used to print a message connectPort = PortNumber 6379 -- Redis port that is passed as an argument to it. The equivalent hedis echo command expects the message to be of type connectAuth = Nothing -- No authentication ByteString. For example: connectDatabase =0 -- SELECT database 0 {-# LANGUAGE OverloadedStrings #-} import Database.Redis connectMaxConnections = 10 -- Up to 10 connections import qualified Data.ByteString as B connectMaxIdleTime = 20 -- Keep connection open for 20 seconds The types of conn, connect, runRedis and ping are given below: www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 33

Developers How To bytes :: B.ByteString You can also retrieve the value of a key using the get bytes = “Hello, World” :: B.ByteString function. For example: main :: IO (Either Reply B.ByteString) {-# LANGUAGE OverloadedStrings #-} main = do import Database.Redis import Control.Monad.IO.Class conn <- connect defaultConnectInfo runRedis conn $ echo bytes main :: IO () main = do Loading the above code in GHCi produces the following output: conn <- connect defaultConnectInfo runRedis conn $ do ghci> main Right “Hello, World” result <- get “a” liftIO $ print result The type signature of the echo function is as follows: Executing the above code in GHCi gives the expected echo result: :: RedisCtx m f => Data.ByteString.Internal.ByteString ghci> :l get.hs ( get.hs, interpreted ) -> m (f Data.ByteString.Internal.ByteString) [1 of 1] Compiling Main Ok, modules loaded: Main. You can set a value to a key using the set function in hedis. An example is shown below: ghci> main Right (Just “apple”) {-# LANGUAGE OverloadedStrings #-} import Database.Redis The liftIO function transforms an IO action into a Monad. Its type signature is shown below: main :: IO (Either Reply Status) ghci> :t liftIO main = do liftIO :: MonadIO m => IO a -> m a The type signature of the get function is as follows: conn <- connect defaultConnectInfo ghci> :t get runRedis conn $ set “a” “apple” get Loading the above set.hs code in GHCi and testing the :: RedisCtx m f => same produces the following output: Data.ByteString.Internal.ByteString -> m (f (Maybe Data.ByteString.Internal.ByteString)) ghci> :l set.hs ( set.hs, interpreted ) [1 of 1] Compiling Main You are encouraged to read the Database.Redis Ok, modules loaded: Main. documentation page that contains a comprehensive list of commands and their usage at https://hackage.haskell.org/ ghci> main package/hedis-0.6.5/docs/Database-Redis.html. Right Ok Accessing the PostgreSQL database The type signature of the set function is shown below: We shall now explore accessing a PostgreSQL database using ghci> :t set the postgresql-simple (0.4.10.0) package. You will need set to install and configure PostgreSQL for your GNU/Linux distribution. Please follow your distribution documentation to :: RedisCtx m f => do so. On Fedora, for example, you can install the database Data.ByteString.Internal.ByteString server using the following command: -> Data.ByteString.Internal.ByteString -> m (f Status) $ sudo yum install postgresql-server postgresql-contrib You can verify the value of the key ‘a’ from the redis-cli command, and it must return the value “apple”: You can then start the database server using the following service command: 127.0.0.1:6379> get a “apple” 34 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers $ sudo service postgresql start , connectPassword = “postgres123” , connectDatabase = “test” You can now install the postgresql-simple package using } the cabal command: execute conn “create table social.users (id INT, fname $ cabal install postgresql-simple VARCHAR(80), lname VARCHAR(80))” () Let us first create a database and a schema using the close conn Postgresql command-line utility psql: Loading the above code in GHCi creates the table social.users $ psql -U postgres as shown below: Password for user postgres: psql (9.3.5) $ ghci create.hs Type “help” for help. GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help postgres=# \\l List of databases Loading package ghc-prim ... linking ... done. Name | Owner | Encoding | Collate | Ctype | Access privileges Loading package integer-gmp ... linking ... done. -------------+----------+-------------+-------------+-------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | Loading package base ... linking ... done. template0| postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/ postgres + [1 of 1] Compiling Main ( create.hs, interpreted ) postgres=CTc/postgres template1 | postgres | UTF8| en_US.UTF-8 | en_US.UTF-8 | Ok, modules loaded: Main. =c/postgres + postgres=CTc/postgres ghci> main (3 rows) Loading package array-0.4.0.1 ... linking ... done. postgres=# CREATE DATABASE test; Loading package deepseq-1.3.0.1 ... linking ... done. CREATE DATABASE Loading package bytestring-0.10.0.2 ... linking ... done. Loading package containers-0.5.0.0 ... linking ... done. postgres-# \\c test Loading package text-0.11.3.1 ... linking ... done. Loading package attoparsec-0.10.4.0 ... linking ... done. You are now connected to database ‘test’ as user Loading package blaze-builder-0.3.1.1 ... linking ... done. ‘postgres’. Loading package dlist-0.5 ... linking ... done. Loading package hashable-1.1.2.5 ... linking ... done. test=# create schema social; Loading package transformers-0.3.0.0 ... linking ... done. CREATE SCHEMA Loading package mtl-2.1.2 ... linking ... done. Loading package old-locale-1.0.0.5 ... linking ... done. test=# \\dn Loading package syb-0.4.0 ... linking ... done. public | postgres Loading package pretty-1.1.1.0 ... linking ... done. social | postgres Loading package template-haskell ... linking ... done. Loading package time-1.4.0.1 ... linking ... done. We can then create a users’ table with an ID, first name Loading package unordered-containers-0.2.3.0 ... linking ... done. and last name using the postgresql-simple package: Loading package primitive-0.5.0.1 ... linking ... done. Loading package vector-0.10.0.1 ... linking ... done. {-# LANGUAGE OverloadedStrings #-} Loading package aeson-0.6.2.1 ... linking ... done. Loading package random-1.0.1.1 ... linking ... done. import Database.PostgreSQL.Simple Loading package scientific-0.2.0.2 ... linking ... done. Loading package case-insensitive-1.0.0.1 ... linking ... done. main :: IO () Loading package blaze-textual-0.2.0.8 ... linking ... done. main = do Loading package postgresql-libpq-0.9.0.2 ... linking ... done. Loading package binary-0.7.4.0 ... linking ... done. conn <- connect defaultConnectInfo Loading package cereal-0.3.5.2 ... linking ... done. { connectUser = “postgres” Loading package entropy-0.2.2.1 ... linking ... done. Loading package tagged-0.6 ... linking ... done. Loading package crypto-api-0.11 ... linking ... done. Loading package cryptohash-0.9.0 ... linking ... done. Loading package network-info-0.2.0.5 ... linking ... done. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 35

Developers How To Loading package uuid-1.3.8 ... linking ... done. ----+-------+------- Loading package postgresql-simple-0.4.10.0 ... linking ... done. 1 | Edwin | Brady You can verify the created table from the psql prompt: (1 row) test=# \\d social.users You can also do batch inserts using the executeMany function. For example: id | integer | executeMany conn “insert into social.users (id, fname, lname) fname | character varying(80) | values (?, ?, ?)” [(“2” :: String, “Simon” :: String, “Marlow” :: String), (“3” :: String, “Ulf” :: String, “Norell” :: String)] lname | character varying(80) | After running the above code, you can check the newly added You can also list the databases in the PostgreSQL server rows in the database from the psql command-line tool: using the query_ function as illustrated below: test=# select * from social.users; {-# LANGUAGE OverloadedStrings #-} id | fname | lname import Database.PostgreSQL.Simple ----+-------+-------- main :: IO () 1 | Edwin | Brady main = do 2 | Simon | Marlow 3 | Ulf | Norell conn <- connect defaultConnectInfo (3 rows) { connectUser = “postgres” , connectPassword = “postgres123” You can also change a record entry using the UPDATE , connectDatabase = “test” statement as shown below: } databases <- query_ conn “SELECT datname FROM pg_database” print (databases :: [Only String]) close conn execute conn “update social.users SET lname = ‘Peyton Jones’ where fname = ‘Simon’” () Executing the above code in GHCi produces the following output: The corresponding entry is updated as seen from the psql prompt: $ ghci show.hs test=# select * from social.users; GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help id | fname | lname ----+-------+-------------- Loading package ghc-prim ... linking ... done. 1 | Edwin | Brady 3 | Ulf | Norell Loading package integer-gmp ... linking ... done. 2 | Simon | Peyton Jones (3 rows) Loading package base ... linking ... done. It is recommended that you catch exceptions when running [1 of 1] Compiling Main ( show.hs, interpreted ) database commands. Consider the following example, where the number of arguments passed does not match with what is Ok, modules loaded: Main. expected: ghci> main {-# LANGUAGE OverloadedStrings #-} [Only {fromOnly = “template1”},Only {fromOnly = “template0”},Only {fromOnly = “postgres”},Only {fromOnly = import Database.PostgreSQL.Simple “test”}] import Control.Exception import GHC.Int You can now insert a record into the databases using the execute function: execute conn “insert into social.users (id, fname, lname) values (?, ?, ?)” [“1” :: String, “Edwin” :: String, “Brady” :: String] After executing the above code, you can verify the database main :: IO () entry from the psql prompt: main = do test=# select * from social.users; id | fname | lname conn <- connect defaultConnectInfo { connectUser = “postgres” Continued on page ...39 36 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers BOOTSTRAP: Building an Interactive Tourism Web Page A well designed, interactive Web page offers satisfaction to the client, user and, above all, to the developer. The authors of this tutorial present an interactive tourism Web page that was created using Bootstrap. The whole process is explained lucidly and the code is all there, so that enthusiasts can wade into it straight away! Bootstrap is a free and open source from MaxCDN when visiting other HTML5, JS and CSS framework for websites. It will be loaded from the cache building well designed, responsive, when they visit our website, resulting in mobile first websites and Web applications, faster website access. at very short notice. Besides, the Twitter Bootstrap framework provides a standard Designing the first page using and consistent way to render Web pages Bootstrap across browsers and devices (from phones and tablets to desktops). In this article, we The first thing any Web developer needs explore the fundamentals of this very handy to do is to create a design for the Web tool, and demonstrate how to create a simple page. Bootstrap provides some predefined yet interactive tourism Web page using website templates, which can be extended, Bootstrap as one of the templates. or websites can be built from scratch. The templates or examples can be found in http:// Get started with Bootstrap getbootstrap.com/getting-started/#examples. Our Web page is divided into four sections To get started, one can download the latest using the marketing template provided by Bootstrap version from http://getbootstrap. Bootstrap: com, copy it in a folder of your choice 1. Navigation bar or include it from CDN. For the example 2. Navigation tab and slide show below, we are going to use CDN, as many 3. Content section users have already downloaded Bootstrap 4. Footer www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 37

Developers How To To get started, add HTML5 DOCTYPE. Bootstrap uses </form> HTML5 elements and CSS properties, which require HTML5 </div><!--/.navbar-collapse --> DOCTYPE at the beginning of the page. </div> <!-- container closed--> <!DOCTYPE html> Adding the navbar-brand class gives the Web page’s <html lang=”en”> name. Following that, there is the form-group div containing Defining <head>: the placeholder for the username and password, followed by two form elements—Sign In and Register, which can be used To build a responsive, mobile first Web page and to ensure to navigate to the required pages. proper rendering in any device, add the following line: Now, let us add a slide show of pictures as the background <meta name=”viewport” content=”width=device-width, initial- for our Web page. The Bootstrap carousel is an interactive scale=1”> slider that is both responsive and flexible enough to contain not just pictures but videos, divs, frames, etc. The code for The next step is to add relevant style sheets and JavaScript the carousel is divided into three parts. The first part, which files to the head section, as follows: is the ‘DOT indicators’, aims at displaying simple dots in the bottom centre of the images or the content to be displayed. <link href=”https://maxcdn.bootstrap.com/bootstrap/3.3.2/css/ These are meant for manual sliding across the different slides. bootstrap.min.css” rel=”stylesheet”> The second part contains the actual content in the form of <link rel=”stylesheet” type=”text/css” href=”CSS/custom.css”> div elements. In our case, we have collected a few images <link rel=”stylesheet” href=”http://maxcdn.bootstrapcdn.com/ that will be shifting around in the background. The last part bootstrap/3.3.2/css/bootstrap-theme.min.css”> contains the controls in the form of left and right arrows, also <link href=”https://maxcdn.bootstrap.com/bootstrap/3.3.2/css/ meant for the user to slide across the content. bootstrap.min.css” rel=”stylesheet”> <script src=”https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/ <div id=”myCarousel” class=”carousel container slide”> jquery.min.js”></script> <ol class=”carousel-indicators”> <!-- Dot Indicators --> <script src=”http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/ bootstrap.min.js”></script> <li data-target=”#myCarousel” data-slide-to=”0”></li> <li data-target=”#myCarousel” data-slide-to=”1” Let’s begin with the <Body> section. class=”active”></li> We need to first define a fixed navigation bar at the top of <li data-target=”#myCarousel” data-slide-to=”2”></li></ol> the Web page: <div class=”carousel-inner”> <!-- slides --> <div class=”item”><img src=”images/pic1.jpg” alt=”” /></ <nav class=”navbar navbar-default”> <!—This will be fixed at the div> top --> <div class=” active item”><img src=”images/pic2.jpg” <div class =”container”> <!—see everything as container--> alt=”” /></div> <div class=”navbar-header”> <div class=”item”><img src=”images/pic3.jpg” alt=”” /></ <button type=”button” class=”navbar-toggle collapsed” data- div></div> toggle=”collapse” data-target=”#navbar” aria-expanded=”false” aria-controls=”navbar”> <!—Slide Navigation --> <span class=”sr-only”>Toggle navigation</span></button> <a class=”left carousel-control” href=”#carousel-example-generic” <a class=”navbar-brand” href=”#Home” style=”margin-top: 0”> role=”button” data-slide=”prev”> <h4><em><strong>Leisurely Getaways</strong></em></h4></a> <span class=”glyphicon glyphicon-chevron-left” aria- </div> hidden=”true”></span> <div id=”navbar” class=”navbar-collapse collapse”> <span class=”sr-only”>Previous</span></a> <form class=”navbar-form navbar-right”> <a class=”right carousel-control” href=”#carousel-example- <div class=”form-group”> generic” role=”button” data-slide=”next”> <input type=”text” placeholder=”Email” class=”form-control”></ <span class=”glyphicon glyphicon-chevron-right” aria- div> hidden=”true”></span> <div class=”form-group”> <span class=”sr-only”>Next</span></a></div> <input type=”password” placeholder=”Password” class=”form- control”></div> Bootstrap offers multiple ways of customising the way the <button type=”submit” class=”btn btn-success”>Sign in</button> carousel is rendered on the browser. <button type=”submit” class=”btn btn-success”>Register</button> The small JavaScript code snippet shown below makes the carousel more interactive: <!-- Java Script to set interval timing for images--> 38 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers <script type=”text/javascript”> <p> Powered by Twitter Bootstrap 3.3.2</p></div> $(document).ready(function() { $(‘.carousel’).carousel({interval: 4000}); You can download the entire source code of this Web page }); from https://github.com/VinayPatkar/Tourist_Bootstrap.git. It contains custom.css and index.html files. </script> As we are done creating a basic Web page using Apart from this, the carousel plugin also offers several Bootstrap, it’s time to now dive deeper into it and explore its options like intervals, pauses and wraps to showcase your more advanced features. For more learning, refer to the links content, which makes the Web page even more dynamic, in given under ‘References’. terms of features. References Closing with the footer [1] http://getbootstrap.com/examples/carousel/ The last section in our Web page, the footer, is going to [2] http://getbootstrap.com/components/#dropdowns contain Help and Terms and Conditions, with text aligned to [3] https://wrapbootstrap.com/ the centre and the right side: By: Shubhra Rana and Vinay Patkar <footer class=”footer”> <div class=”span4 text-center”> Shubhra Rana is a software development engineer at Dell R&D, <p> <a href=”#”>Help</a> &nbsp <a href=”#”> Terms & Conditions</ Bengaluru, and is interested in network security and cryptography. a> &nbsp &copy; Leisurely Getaways 2014</p> Vinay Patkar works as a software development engineer at Dell India </div></footer> R&D Centre, Bengaluru, and has close to two years’ experience in <div class=”span4 text-right”> automation and Windows Server OS. He is interested in virtualisation and cloud computing technologies. Continued from page ...36 main :: IO () main = do , connectPassword = “postgres123” , connectDatabase = “test” conn <- connect defaultConnectInfo } { connectUser = “postgres” result <- try (execute conn “insert into social.users (id, , connectPassword = “postgres123” fname, lname) values (?, ?, ?)” [“4” :: String, “Laurel” :: , connectDatabase = “test” String]) :: IO (Either SomeException Int64) } case result of users <- query_ conn “SELECT fname, lname FROM social.users” Left ex -> putStrLn $ “Caught exception: “ ++ show ex forM_ users $ \\(fname, lname) -> Right val -> putStrLn $ “The answer was: “ ++ show val putStrLn $ Text.unpack fname ++ “ “ ++ Text.unpack lname close conn close conn The error is observed when the main function is The output after executing the above code in GHCi executed as shown below: returns the actual data: ghci> main ghci> main Caught exception: FormatError {fmtMessage = “3 ‘?’ characters, Edwin Brady but 2 parameters”, fmtQuery = “insert into social.users (id, Ulf Norell fname, lname) values (?, ?, ?)”, fmtParams = [“4”,”Laurel”]} Simon Peyton Jones You can also retrieve multiple records from the database Please refer to the Database.PostgreSQL.Simple and use the results, with the help of a map function. An documentation for more examples and usage at example is illustrated below: https://hackage.haskell.org/package/postgresql- simple-0.4.10. {-# LANGUAGE OverloadedStrings #-} By: Shakthi Kannan import Database.PostgreSQL.Simple import Control.Monad The author is a free software enthusiast and blogs at shakthimaan.com import Data.Text as Text www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 39

Developers How To Writing a Basic Framebuffer Driver This article deals with the basic structure of a framebuffer and will interest those who know how to write a character device driver. The author has tried to simplify the topic as much as possible so as to make it accessible to more readers. Aframebuffer driver is an intermediate layer in Linux, which hides the complexities of the underlying video ioctl commands include FBIOGET_VSCREENINFO device from the user space applications. From the and FBIOPUT_VSCREENINFO. As you may have point of view of the user space, if the display device needs to guessed, the FBIOGET_VSCREENINFO call will ask the hardware about the screen information, and FBIOPUT_ be accessed for reading or writing, then only the framebuffer VSCREENINFO will set the screen information. Some device such as /dev/fb0 has to be accessed. If you have more other ioctl commands include FBIOGETCMAP, FBIOPAN_ than one video card in your computer, then each will be DISPLAY, etc. You can find the list of commands in the assigned separate device nodes like /dev/fb0.. /dev/fb1.. /dev/ uapi/linux/fb.h file in the kernel source. fbX (X being the minor number of the device). Now, let’s look at how to write a module that will We also have many different ways to access a framebuffer. work as a very minimal framebuffer driver, with only the To get a snapshot of your screen, you can just use the cp required components. command, as follows: We need a few header files in our module, and with the basic structure of a module our starting point becomes… cp /dev/fb0 myscreen From a programmer’s point of view, you can read #include <linux/module.h> and write to this device, the main use being mmap. You #include <linux/kernel.h> can map the video memory in the user space memory, #include <linux/errno.h> and then you can control each and every pixel of your #include <linux/string.h> screen. We also have a set of ioctl calls to get and set #include <linux/mm.h> different parameters of the video hardware. A few #include <linux/slab.h> #include <linux/delay.h> 40 | april 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers #include <linux/fb.h> We are assuming that PCI_VENDOR_ID_XXX and PCI_ #include <linux/init.h> DEVICE_ID_XXX are defined elsewhere with the correct vendor #include <linux/pci.h> and device ID. This table should always be null terminated. To explain MODULE_DEVICE_TABLE in a very simple way –- it static int __init ourfb_init(void) informs the kernel that this driver is to be used if it finds any PCI { device with the mentioned vendor and device IDs. When the kernel finds the device, it calls the probe callback function; and return pci_register_driver(&ourfb_driver); if it sees that the device is removed, then it will call the remove } callback function. A detailed discussion on PCI drivers is outside static void __exit ourfb_exit(void) the scope of this article. { static int ourfb_pci_init(struct pci_dev *dev, const struct pci_unregister_driver(&ourfb_driver); pci_device_id *ent) } { module_init(ourfb_init); module_exit(ourfb_exit); struct fb_info *info; MODULE_LICENSE(“GPL”); struct ourfb_par *par; struct device *device = &dev->dev; So now we have a very basic module with the required init int cmap_len, retval; and exit function, but we have not yet defined ‘ourfb_driver’ info = framebuffer_alloc(sizeof(struct ourfb_par), device); which we are using in the code to register in the PCI subsystem. if (!info) { static struct pci_driver ourfb_driver = { return -ENOMEM; .name = “ourfb”, } .id_table = ourfb_pci_tbl, par = info->par; .probe = ourfb_pci_init, info->screen_base = framebuffer_virtual_memory; .remove = ourfb_pci_remove, info->fbops = &ourfb_ops; info->fix = ourfb_fix; }; info->pseudo_palette = pseudo_palette; info->flags = FBINFO_DEFAULT; In the driver structure, we have defined only the required if (fb_alloc_cmap(&info->cmap, cmap_len, 0)) part. If you want to use power management in your driver code and provide Suspend and Resume functionality to your return -ENOMEM; hardware, then you can define that in the driver. But here we if (register_framebuffer(info) < 0) { are leaving them out as they are optional. fb_dealloc_cmap(&info->cmap); In ourfb_pci_tbl, we have to mention the vendor ID return -EINVAL; and the device ID of the hardware for which you are } writing the driver. pci_set_drvdata(dev, info); return 0; static struct pci_device_id ourfb_pci_tbl[] = { } { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX, PCI_ANY_ID, PCI_ static void ourfb_pci_remove(struct pci_dev *dp) { ANY_ID }, struct fb_info *p = pci_get_drvdata(dp); {0} unregister_framebuffer(p); fb_dealloc_cmap(&p->cmap); }; MODULE_DEVICE_TABLE(pci, ourfb_pci_tbl); THE COMPLETE MAGAZINE ON OPEN SOURCE Your favourite Magazine on Open Source is now on the Web, too. OpenSourceForU.com Follow us on Twitter@LinuxForYou www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | april 2015 | 41

Developers How To iounmap(p->screen_base); struct fb_fix_screeninfo { framebuffer_release(p); } char id[16]; /* identification string */ The above code is an example of a very simple probe unsigned long smem_start; /* Start of frame buffer function. Now, let’s talk a little about what we have used in our probe function. mem (physical address) */ framebuffer_alloc: This creates a new framebuffer __u32 smem_len; /* Length of frame buffer mem */ information structure. It also reserves the size for the driver’s private data (info->par). You might have guessed by now __u32 type; /* FB_TYPE_* */ that ourfb_par is our private data. This function will return a pointer to struct fb_info or it returns NULL if it fails. __u32 type_aux; /* Interleave for interleaved Planes */ ourfb_par: As already said, this is the private data of our __u32 visual; /* FB_VISUAL_* */ driver. It is not a required component but it is recommended that you have it in your driver. At any point of time, this structure will __u16 xpanstep; /* zero if no hardware panning */ have information about the hardware state of the graphics card. __u16 ypanstep; /* zero if no hardware panning */ framebuffer_virtual_memory: This is not defined in our code, but it is actually the virtual memory address for the framebuffer. __u16 ywrapstep; /* zero if no hardware ywrap */ We get this address after remapping the resource address. The following code will show you how we get this address: __u32 line_length; /* length of a line in bytes */ unsigned long mmio_start; /* Start of Memory Mapped I/O (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ __u32 accel; /* Indicate to driver which specific chip/card we have */ __u16 capabilities; /* FB_CAP_* */ __u16 reserved[2]; /* Reserved for future compatibility */ }; unsigned long addr, size; flags: This will indicate the type of hardware acceleration addr = pci_resource_start(dev, 0); our driver is capable of. size = pci_resource_len(dev, 0); if (addr == 0) fb_alloc_cmap: This allocates memory for the colour map, which our driver is going to use. return -ENODEV; framebuffer_virtual_memory = ioremap(addr, 0x800000); register_framebuffer: This is the most important function that will actually register our framebuffer with the framebuffer layer. ourfb_ops: This structure will define the operations that we This function is responsible for creating the device nodes /dev/fb*. will allow on our framebuffer. We can have many operations here which are similar to any character device driver, like Note: In the probe function, at any stage, if the open, read, write, release, ioctl, etc. But the operations that we initialisation fails, we have to undo whatever we have done have to provide are fb_fillrect, fb_copyarea and fb_imageblit. before that, and then need to return an appropriate error value. Regarding the other operations, even if we do not mention them in our ops structure, they will be taken care of automatically In the ourfb_remove function, we are unwinding what we by the framebuffer layer by default. If we need any customised have done in the probe function in a reverse manner. functions for our driver, then we have to provide for them also. We have just looked at how to create a very simple Fortunately, the framebuffer layer has three functions: framebuffer device, though we have not touched upon cfb_fillrect, cfb_imageblit and cfb_copyarea. We can use any hardware related topics here. But when we work with these functions in our driver instead of writing our own an actual framebuffer driver that is responsible for video fb_fillrect, fb_copyarea and fb_imageblit functions. But if hardware, we need to give all the hardware initialisation you are writing a driver for hardware that supports hardware routines in the probe function. If you want to see the code of acceleration, then you have to write your own functions. any framebuffer device driver, you can find it in the drivers/ video/fbdev/ folder of the Linux source tree. static struct fb_ops ourfb_ops = { Another complicated scenario: Some graphical hardware will .owner = THIS_MODULE, have support for two monitors, where each display can have its own unique data. In this case, each display should have its own separate .fb_fillrect = cfb_fillrect, framebuffer device, which means separate struct fb_info. Some hardware will have the double-buffering capability. .fb_imageblit = cfb_imageblit, By: Sudip Mukherjee .fb_copyarea = cfb_copyarea, The author is the maintainer of the Silicon Motion SM712 }; framebuffer driver in the mainline kernel. He works as an embedded Linux developer at Vector India Pvt Ltd, a renowned embedded ourfb_fix: This structure will contain fixed information training institute. He can be reached at [email protected] about our hardware. The following is the structure as defined in the header file: 42 | april 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

How To Developers Develop Multi-device Web Based Games with HTML5 The gaming design and development industry is growing exponentially. If you are interested in creating a Web based game, try out this HTML5 sample script. With the Internet’s capabilities evolving at a fast ƒ The game platform – HTML5, JavaScript, etc pace and browsers now available in almost every ƒ Plugins – ActiveX, Shockwave, etc handheld device, Web based games are common ƒ Browser support – Internet Explorer, FireFox, Google these days. A study suggests that users spend more time on Web based games than on traditional console games. Chrome, etc A Web game as the term suggests is an application HTML5 that you can launch in your browser and play. There are several plugins available right now, which allow us to play HTML5 has good support for lots of game frameworks, and these standard games and most popular Web browsers (like with JavaScript support, it makes a great platform for game Chrome, Firefox and IE) support them. Currently, there has development. Table 1 specifies the function and technology been an evolution from single player games to multi-player used, along with the features. games across the Internet. A few examples are listed here: EaselJS http://www.powersoccer.com http://www.miniclip.com/games/en/ EaselJS is a simple JavaScript library that makes working with HTML 5 Canvas very efficient. It provides solutions for How a Web based game is designed working with graphics and interactivity with HTML5 Canvas. It also provides an API that is familiar to Flash developers, There are three main stages in a Web based game: including a hierarchical display list and DOM Level 2 events. ƒ The presentation or UI Source: http://www.createjs.com/EaselJS ƒ Interpretation of the user’s actions ƒ Calculation of the results based on the above factors Sample script Any Web based game has to go through these stages to Let’s try to create a simple animation clip using EaselJS. work well. These specifics may vary for a few games but are The following is the code that will help to demonstrate the the important aspects to keep in mind before developing a animation: game engine. In some games, users may be asked to repeat certain actions, so your script has to be made to interpret <!DOCTYPE html> those actions to achieve specific results in the game. <html lang=”en”> <head> Several requirements are involved in the development of a Web based game, such as: <title>TITLE</title> www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 43

Developers How To Table 1: HTML5/JavaScript features Function Technology Features Audio Web audio API API for processing and synthesising audio. Graphics WebGL (OpenGL ES 2.0) API for rendering 3D and 2D images. Compatible with brows- ers supported by plugins. Note: Not supported on mobiles but can use OpenGL wrappers Input Touch events, gamepad API, device sensors, WebRTC – Getusermedia can get hardware access WebRTC, full screen API, pointer lock API Language JavaScript (or C/C++ using Emscripten to JavaScript has support for lots of game engines/frameworks compile to JavaScript) Networking WebRTC and/or WebSockets Allows interactive sessions between user’s browser and server Storage IndexedDB Client side storage for data Web HTML, CSS, SVG, social API Types of APIs and languages for development Source: Mozilla Development Network and HTML5 Forum <style> getElementById(“stageCanvas”); #stageCanvas { //copy the canvas bounds to the bounds instance. background-color:#333333; bounds = new Rectangle(); } bounds.width = canvas.width; bounds.height = canvas.height; </style> <!-- import the Easel library. Downloaded from: //pass the canvas element to the EaselJS Stage instance stage = new Stage(canvas); http://easeljs.com/ --> <script src=”scripts/easel.js”></script> //Create an EaselJS Graphics element to create the <script> //commands to draw a circle var g = new Graphics(); //EaselJS Stage instance that wraps the Canvas element //stroke of 1 px g.setStrokeStyle(1); var stage; var circle; //Set the stroke color, using the EaselJS g.beginStroke(Graphics.getRGB(255,255,255,.7)); //radius of the circle Graphics that we will draw. var CIRCLE_RADIUS = 10; var circleXReset; var bounds; //initialize function, called when page loads. //draw the circle function init() g.drawCircle(0,0, CIRCLE_RADIUS); { circle = new Shape(g); //check and see if the canvas element is supported in //set the initial x position, and the reset position circle.x = circleXReset = -CIRCLE_RADIUS; //the current browser if(!(!!document.createElement(‘canvas’).getContext)) //set the y position { circle.y = canvas.height / 2; var wrapper = document.getElementById(“canva //add the circle to the stage. sWrapper”); stage.addChild(circle); wrapper.innerHTML = “Your browser does not //tell the stage to render to the canvas appear to support” +”the HTML5 Canvas element”; stage.update(); Continued on page... 46 return; } //get a reference to the canvas element var canvas = document. 44 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

Overview Developers Popular Open Source IDEs for Web Development Let us explore popular open source IDEs for Web development. The IDEs mentioned here are just to whet the appetite of readers so that they may delve deeper into the subject. The article does not go too deep into specifics but informs just enough to rouse the curiosity of a newbie. Programmers are always looking for a handy piece of for your projects, so if you use that service, the IDE ties in software that acts as a code editor, compiler and debugger, those services perfectly. It’s based on Eclipse, and supports while also providing a fancy GUI. One doesn’t wish to JavaScript, HTML, DOM, CSS, code-completion, JavaScript type every piece of code in the text editor or use the command debug capabilities, etc. prompt. IDEs always maximise productivity by saving time and removing redundant tasks. For such reasons programmers Joomla look for IDEs that provide a large range of features or those that meet their specific requirements. This article lists out a few open Joomla is a content management system (CMS) that allows source IDEs used for Web development. Note that they are not users to build websites and online applications. It is an easy- ranked in any particular order. to-use, extensible open source software. This CMS keeps track of every piece of content on your website—photos, Eclipse text, music or videos. It is used in many corporate websites, portals, online news magazines, e-commerce sites, for Eclipse is a free and open source community of tools online reservations, government applications, SME business and projects and collaborative working groups, on which websites... and the list goes on. Joomla is offered under many development frameworks like Web projects and GPL version 2.0 and its source code can be found at https:// applications are based. Most developers prefer IDEs rather github.com/joomla. than console-like text editors. Eclipse projects are focused on building an open development platform comprising Bluefish extensible frameworks, tools and runtimes for building, deploying and managing software across its life cycle. Bluefish is a full-featured Web editor for developers and Web programmers, which runs on Linux, Windows or Mac. It’s Aptana Studio an open source project released under the GNU license. It is considered by far the most powerful among HTML editors. Aptana Studio is another widely used IDE for Web Features include a code-sensitive spell check, auto-complete development. It’s available either as a standalone app or as a in many different languages (HTML, PHP, CSS, etc), plugin for Eclipse. Aptana (the company) also offers hosting snippets, project management and auto-save. www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | April 2015 | 45

Developers Overview KompoZer modular pieces of software called modules. Though initially it was developed for Java programmers, it soon became popular KompoZer is a lightweight application, but it is a good choice for Web development. NetBeans is cross-platform and even for advanced programming tasks. supports a compatible JVM. This open source IDE is a sweet deal—whether you’re Brackets developing in PHP, Ruby on Rails, JavaScript or something else, you’ll find rich editing features, as well as support for FTP and Brackets is an open source code editor written in HTML, MySQL. With PHP, it offers light on-the-go debugging, alerting JavaScript and CSS with a focus on Web development. It is you to errors as you type. Whether you’re working with Python, licensed under MIT by Adobe Systems. Just like NetBeans, PHP, Ruby, Perl, HTML, CSS or JavaScript, KompoZer provides it’s also cross-platform. Its features include Quick Edit (inline a clean, intuitive interface with advanced editing capabilities and editing of HTML, CSS, colour properties and JavaScript), live integrated tools for the most functionality. preview (pushes code instantly to the browser, with no page refresh required), Quick docs, and more. Cloud9 The above listed IDEs are among the many free or Cloud9 is an open source online IDE with the support of up open source varieties available for developers. They are to 40 programming languages. With a pre-setup workspace, worth a try. collaborative coding features and Web development features, it allows developers to get started with coding immediately. Its By: Vinay Patkar source code can be found in https://github.com/c9/core/ GitHub. The author works as a software development engineer at Dell India NetBeans R&D Centre, Bengaluru, and has close to two years’ experience in automation and Windows Server OS. He is interested in virtualisation NetBeans is another open source IDE written entirely in Java and cloud computing technologies. by Oracle. It allows applications to be developed from a set of Continued from page... 44 <div width=”400” height=”300” id=”canvasWrapper”> <canvas width=”400” height=”300” id=”stageCanvas”></ Ticker.setFPS(24); canvas> Ticker.addListener(this); </div> } </body> //function called by the Tick instance at a set interval </html> function tick() { To execute this sample script, follow the instructions given below: //check and see if the Shape has gone of the right 1. Copy this script and paste it into Notepad and rename it //of the stage. if(circle.x > bounds.width) game.html { 2. Download the easel.js file and place it in the Scripts folder 3. Run game.html in the browser //if it has, reset it. circle.x = circleXReset; Over the last few years, games built for browsers have been } deployed on laptops, tablets, mobiles or any other computing device. With HTML5, we have the true power of writing an //move the circle over 10 pixels application once and deploying it anywhere. circle.x += 8; By: Gobind Vijayakumar and Avinash Bendigeri //re-render the stage stage.update(); Gobind Vijaykumar works in the OS engineering group of } Dell India R&D Centre, Bengaluru, and has over six years of </script> experience in server operating systems and storage solutions. Avinash Bendigeri is a software development engineer at Dell </head> R&D Centre, Bengaluru. He is interested in the automation <body onload=”init()”> and systems management domain. 46 | April 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

Let’s Try Developers Qt5: GUIs with QtQuick and QML In the previous article on Qt5 (Part 2), we built a small server program that served a random fortune cookie to anyone who connected to it using TCP, and we tested it out by telneting into it. In the third and final part of this series, we’re going to build a small GUI client to go with the server. We’ve been dabbling with Qt5 for some time now, it using nothing but JavaScript. The second part is QtQuick without doing the one thing that Qt is famous itself, which is a set of components (or controls) that you can for – the GUIs. Now, we’re finally going to build make use of in your QML based GUIs. that GUI in the easy and fun new way using QtQuick and QML. We’ll be building a fairly complex GUI with a bit of QtQuick and QML were first conceived as a new way of configuration headroom, without touching a single line of writing UIs for Qt applications. These were meant for people C++ code for the GUI logic. without much of a programming background as, back then, Qt was used to write applications for Nokia’s Maemo and then That’s not to say we won’t be using C++ at all –- we’ll MeeGo (and even today, it’s used to write applications for use it to write a QML component that does the networking Sailfish OS). QtQuick 1.0 was quickly hacked together and bits for us. In the bargain, you’ll also learn how to extend did its job well, but wasn’t much of a performer. However, QML and QtQuick programs with C++ code. But first, here’s that didn’t stop it from being used outside the mobile a primer on QtQuick and QML. development space; it was used widely in KDE’s Plasma Active and eventually in parts of Plasma 4 itself. QtQuick and QML QtQuick 2.0, which came with Qt5, was a major overhaul. QtQuick made its debut in Qt4.7 but only became the Because QtQuick became so popular with developers on recommended way of building GUIs in Qt5. Originally, both desktops and mobile devices, its creators had to make it QUICK stood for Qt User Interface Construction Kit, but now a first-class way to build GUIs. So with Qt5, they redid the it’s just called QtQuick. entire GUI rendering pipeline, making the whole thing 3D based, and using OpenGL as a backend. The downside to this So what is it? Well, the answer comes in two parts. The is that QtQuick 2.0 requires OpenGL support to run, even if first is QML (again, originally Qt Markup Language, but the GUI consists only of 2D widgets, as these widgets are now just called QML), a declarative language very much like internally implemented as OpenGL surfaces. The upside is JavaScript which can be used to declaratively describe the that QtQuick 2.0 GUIs are extremely fast. GUI and its logic. That’s right; you build the GUI and script www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | april 2015 | 47

Developers Let’s Try So how do you run QML applications on Qt5 on systems Computers are not where there’s no 3D support? Well, QtQuick 1.0 still ships intelligent. They only think with Qt5, so you can use that. Or you can drop to using standard C++ GUIs, which can fall back to 2D rendering if 3D they are. isn’t available on the system. So that's enough of theory. Let’s build something. Starting off Figure 1: Fortune cookie Open up QtCreator and start a new project. This time, choose worry if you still don’t understand how to write code Qt Quick Application (and not Qt Quick UI, which creates a yourself), we’re ready to start building our own GUI. QML-only application with no C++ code). Hit Choose, set the location and hit Next. Building the GUI Now you’ll be presented with a drop-down list of component The first thing you should do is delete the MainForm.ui.qml sets to use for the application. You’ll need to use the latest available file in the Projects pane. We won’t be needing it since we’ll Qt Quick Controls (at the time of writing, this is Qt Quick Controls be writing the entire UI inside main.qml. 1.3). Qt Quick Controls is a set of desktop application widgets implemented on top of raw Qt Quick 2 (which is also available if Now comes the difficult bit. main.qml in our program you want to use it). Once you’re done, hit Next. is 150 lines long, which is a tad too long to print out in this magazine. So we’re going to have to do it a little differently. Run through the rest of the wizard. Make sure Desktop is selected when you’re selecting the kits to use for the First of all, you’re going to have to fetch all the source application. Check the summary, and then finish the wizard to code for this article. It’s available on my GitHub account, at get started with the code. https://github.com/BaloneyGeek/FortuneClientExample. Like the last article, this is a fully functioning application, so you QML can just clone the repository, build it and run it. At this point, you’ll be dropped into the editor with main. But let’s see some of the code at least. We start with qml open. You’ll be able to inspect this file to figure out what the imports: QML applications look like. But let me help you out. import QtQuick 2.4 At the top of the code, you’ll see a bunch of import import QtQuick.Layouts 1.1 statements, like in Python. These lines import the QML import QtQuick.Controls 1.3 components that you’ll be using to write your applications. In import QtQuick.Window 2.2 the sample main.qml that opens up, the import lines are: import QtQuick.Dialogs 1.2 import QtQuick 2.4 import Fortune 1.0 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.2 So first, QtQuick 2 itself is imported, followed by a We’re importing a whole bunch of QtQuick extensions, bunch of extensions, including Controls, which implement including Layouts, which we’ll use to build the layout of the GUI widgets; Dialogs, which are used to create pop-up GUI (as the name suggests). dialogue boxes, and Window, which is used to create the main application window in QML. The last thing we’re importing—Fortune 1.0—does not quite exist yet, so QtCreator is going to give it a red underline. QML components can be written in QML (remember that We’ll build this component in C++ later. it’s basically JavaScript; it’s actually powered by Google’s V8, so it’s a full-blown programming language to work in) or The next few lines set up the application window, and C++. We’re going to write a component in C++ to make the populate the menu bar and the status bar. We won’t reproduce the QML GUI talk to the fortune cookie server. code in print, but it’s simple enough and one look will give you an idea of what’s going on. What you’ll find interesting is that The rest of the code describes the GUI. It’s very much there are ampersand characters in some of the strings. This is to like HTML. There’s one root element (in this case, an set up keyboard shortcuts—the letter right after the ampersand ApplicationWindow, which encapsulates the rest of the symbol becomes the keyboard shortcut for that item. element hierarchy). Notice that all elements look exactly like JSON objects, with properties that can either be other objects Then we come to the main UI form of the program. (like strings or numbers) or JavaScript functions. The UI features one giant label in the centre top part of the window displaying the fortune cookie, and one button Once you’ve figured out what QML looks like (don’t at the centre bottom that can be clicked to attempt to get a 48 | april 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com

Let’s Try Developers new fortune cookie: At this point, you might find QML overwhelming—let’s face it, we’ve already dealt with about 10 components and a lot Item { more properties of each. The truth is, QML’s component sets id: mainForm; are pretty huge, and to study each one of them in-depth before anchors.fill: parent; writing code is impractical. Hence this—an application in QML to get you started, and the component reference manuals to refer GridLayout { to as you go along, which are linked to at the end of the article. rows: 2; columns: 1; This brings us to the one component that we must build rowSpacing: 32; ourselves, in order to make this GUI talk to the fortune server. This is what it looks like: anchors.centerIn: parent; FortuneClient { id: fortuneClient; Label { onHaveFortune: mainFortuneLabel.setText(fortune); id: mainFortuneLabel; Layout.maximumWidth: 600; function setServerPort() { Layout.alignment: Qt.AlignHCenter | serverHost = serverTextField.text; serverPort = portTextField.text; Qt.AlignVCenter; text: qsTr(“Set a server, and click the Get statusBarText.text = qsTr(“OK: Server set to %1:%2”. Fortune button”); arg(serverHost).arg(serverPort)); wrapMode: Text.Wrap; } horizontalAlignment: Text.AlignHCenter; } font.pointSize: 36; And to explain how it works will involve another theory function setText(mtext) { class and a bit of C++ coding. text = qsTr(mtext); horizontalAlignment = Text.AlignLeft; The QQuickItem and the QQmlApplicationEngine horizontalAlignment = Text.AlignHCenter; To load a QML-based UI into a Qt application, you } start by creating a master QApplication instance } (like all other Qt applications), but then you create a QQmlApplicationEngine instance, into which you load up Button { your QML file. This engine executes your QML script and id: getFortuneButton; takes care of all the plumbing for you. Layout.alignment: Qt.AlignHCenter | In actual code, it looks something like this: Qt.AlignVCenter; QApplication app; text: “Get Fortune”; QQmlApplicationEngine engine; onClicked: fortuneClient.getNewFortune(); engine.load(QUrl(QStringLiteral(“qrc:/main.qml”))); } } True, it’s just three lines. The engine provides a standard QtQuick environment, so all QML components This implements the main form. Notice that we have a that are installed on the user’s system are available for the setText() function as a part of the main label to change its programmer to use. text. This will be triggered by the Fortune component when it obtains a new fortune cookie from the server. But what about custom components? We’ll need to use one, so let’s figure out how to inject one into the We’ve also had to reset the horizontal alignment every QQmlApplicationEngine. It turns out that like the QApplication time we change the text. This is because every time the instance (which works at the global level and doesn’t need to be text is changed, the new text is rendered with a very weird touched), the QQmlApplicationEngine is also a global object, alignment. Whether this is a bug or by design is unclear, but into which we can inject custom components at will. resetting the alignment seems to fix this. Now what about those components themselves? Well, The next few lines implement the server selection technically, any object that inherits from QObject and implements dialogue box. Again, this is fairly simple but somewhat long, the meta-object system can be used as a QML component. and to save space, we won’t reproduce it in print. Remember, QML components don’t have to be visible GUI widgets www.OpenSourceForU.com | OpEN SOUrCE FOr YOU | april 2015 | 49

Developers Let’s Try only—if you use the HTML analogy, some QML components are public slots: like <script> tags and are not rendered on the screen. void getNewFortune(); If you do want to create a widget, you need to inherit }; from QQuickPaintedItem. This base class has a lot of glue logic that’s needed for painting on the screen already There’s a lot that’s important here. implemented, and it’s easier to get access to the OpenGL Let’s begin with the Q_PROPERTY macros, which tell context through this. the MOC to expose properties to the QML environment. The minimal syntax looks like this: If you don’t need screen access (like us), you can simply derive from QObject or if you want some of the glue taken Q_PROPERTY(property_type property_name READ read_function care of, you can derive from QQuickItem. QQuickPaintedItem WRITE write_function) derives from this and adds the screen real estate management logic, but does handle screen events; so if you want a So now you’ll know that the first Q_PROPERTY line exposes component that triggers certain actions within the application a QString property, called serverHost, to the QML environment. based on GUI events (without being visible), you need to To read this property, the serverHost() function is called, and to derive from QQuickItem. We won’t need any of the special write to this property, the setServerHost() function is called. functionality when we implement the fortune client, but we’ll derive from QQuickItem anyway. Now let’s take a look at how those functions are implemented. The reader function, serverHost(), is declared The code const and simply returns a QString. That’s all you need to do - declare your function const, which means telling the Let’s begin. This is what the FortuneClient class looks like: compiler this function doesn’t change the state of the object, and return some data of the property type. #include <QQuickItem> #include <QString> Now you’ll have to do a little hackery with integer data. #include <QByteArray> QML has an integer data type, and C++ has many integer #include <QTcpSocket> data types, depending on how many bits you want to use. When you’re specifying a Q_PROPERTY, however, you class FortuneClient : public QQuickItem can only use a standard int as its type, since all the different { qint and quint types don’t have equivalents in the QML environment. So your handler functions must take care to Q_OBJECT check ranges and cast them into properly-sized integers. Q_PROPERTY(QString serverHost READ serverHost WRITE setServerHost) The other very important bit that you need to know is Q_PROPERTY(int serverPort READ serverPort WRITE how the signal and slot mechanisms work with QML. setServerPort) First of all, there are two ways in which you can execute private: a C++ function from within the QML environment. The first is to precede a function declaration with the Q_INVOKABLE quint16 mPort; macro, as follows: QString mHost; Q_INVOKABLE void someFunction(QString some_arg); QTcpSocket * clientSocket; This makes the function visible from the QML public: environment. All functions, even public ones, are not visible from the QML environment, due to security concerns. FortuneClient(); ~FortuneClient(); The second way is to simply declare the function as a public slot. All public slots are visible from the QML QString serverHost() const; environment. And that’s what we have done here with void setServerHost(QString host); getNewFortune()—declared it as a slot. quint16 serverPort() const; void setServerPort(int port); Now for the signals. When you define signals that are to be accessed from the QML environment, you must stick to signals: some naming conventions. You must use camelCase(), with the initial letter being lower case. This is because in the QML void haveFortune(QString fortune); environment, the signal gets turned into a property, with the name onCamelCase, to which you assign a function, JavaScript or C++, which gets executed when the signal is emitted. For example, 50 | april 2015 | OpEN SOUrCE FOr YOU | www.OpenSourceForU.com


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook