diff --git a/ImgHandler.py b/ImgHandler.py
new file mode 100644
index 0000000..ece2a90
--- /dev/null
+++ b/ImgHandler.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+import config
+import re
+import math
+import json
+import random
+import requests
+import time
+
+class ImageHandler(object):
+ """docstring for ImageHandler"""
+ def __init__(self, **kwargs):
+ super(ImageHandler, self).__init__()
+ self.path = kwargs.get('path', config.img_base_path)
+
+ def write_image(self, image):
+ if(image):
+ _id = self._generate_image_id()
+ _type_re = re.compile(r'wx_fmt=\w+')
+ _types = _type_re.findall(image)
+ end = ''
+ print(image)
+ if(len(_types) == 0 or _types[0] == 'wx_fmt=1'):
+ end = '.png'
+ path = self.path + str(_id) + end
+ else:
+ end = '.' + re.sub('wx_fmt=', '', _types[0])
+ path = self.path + str(_id) + end
+ f_img = open(path, 'w')
+ r = requests.get(image)
+ f_img.write(r.content)
+ f_img.close()
+ time.sleep(3)
+ # if you want to change the path where the images will be put, change config file and this path config.
+ path = '/imgs' + str(_id) + end
+ return path
+ else:
+ return ''
+
+
+ def _generate_image_id(self):
+ chars = 'QWERTYUPLKJHGFDSAZXCVBNMqwertyuplkjhgfdsazxcvbnm123456789'
+ length = len(chars)
+ _id = ''
+ for i in range(15):
+ _id = _id + chars[math.trunc(random.random()*length)]
+ return _id
diff --git a/README.md b/README.md
index 3e0ca22..1048dda 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,4 @@
# WechatScraper
-A python wechat official account scrawler, using sougou search engine.
-### Needed
-Python + Selenium + PhantomJS + MySQL
-
-### MySQL
-sql folder is for mysql.
-
-connect mysql and type ``` source ```, then drag the file into the command lines, the table will automatically be created.
+# A python wechat official account scrawler, using sougou search engine.
+# selenium needed
diff --git a/WechatScraper.py b/WechatScraper.py
index 42af888..354e6c1 100644
--- a/WechatScraper.py
+++ b/WechatScraper.py
@@ -2,6 +2,7 @@
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
+from pyvirtualdisplay import Display
import time
import re
import json
@@ -9,12 +10,16 @@
import config
import utils
-browser = webdriver.PhantomJS()
+display = Display(visible=0, size=(1366, 768))
+display.start()
+print('Display start')
+
+browser = webdriver.Firefox()
class WechatScraper():
- def __init__(self, ws_config, **kwargs):
- config = utils.merge(ws_config, config)
+ def __init__(self, **kwargs):
+ self.config = config
"""
query: keyword
@@ -24,7 +29,7 @@ def __init__(self, ws_config, **kwargs):
def get_article_list_by_keyword(self, query, page=1):
query = 'query=' + query
page = 'page=' + str(page)
- built_url = self._build_url(config.article_search_url, ['query', 'page'], [query, page])
+ built_url = self._build_url(self.config.article_search_url, ['query', 'page'], [query, page])
article_list = []
browser.get(built_url)
@@ -63,7 +68,7 @@ def get_article_by_url(self, url):
if(raw_avatar):
avatar = re.sub(re.compile(r'[^"]+"'), '', raw_avatar[0], 1).replace('";', '')
page_content = browser.find_element_by_id('img-content')
- ems = page_content.find_elements_by_css_selector('.rich_media_meta_list>em')
+ ems = page_content.find_elements_by_css_selector('.rich_media_meta_list>em')
author = ''
if(len(ems)>1):
author = ems[1].text
@@ -80,7 +85,7 @@ def search_gzh_by_keyword(self, query, **kwargs):
page = kwargs.get('page', 1)
query = 'query=' + query
page = 'page=' + str(page)
- built_url = self._build_url(config.gzh_search_url, ['query', 'page'], [query, page])
+ built_url = self._build_url(self.config.gzh_search_url, ['query', 'page'], [query, page])
browser.get(built_url)
gzh_list = browser.find_elements_by_css_selector('.news-list2 li')
for i in range(len(gzh_list)):
@@ -109,7 +114,7 @@ def search_gzh_by_keyword(self, query, **kwargs):
def get_gzh_message(self, wechatid):
query = 'query=' + str(wechatid)
page = 'page=' + str(1)
- built_url = self._build_url(config.gzh_search_url, ['query', 'page'], [query, page])
+ built_url = self._build_url(self.config.gzh_search_url, ['query', 'page'], [query, page])
browser.get(built_url)
gzh_list = browser.find_elements_by_css_selector('.news-list2 li')
gzh_url = gzh_list[0].find_element_by_css_selector('.img-box a').get_attribute('href')
@@ -154,7 +159,7 @@ def get_gzh_message(self, wechatid):
"""
- below here are some private functions
+ below here are some common functions
"""
diff --git a/config.py b/config.py
index b4a72c9..b3a2179 100644
--- a/config.py
+++ b/config.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-# config file
import pymysql.cursors
@@ -7,12 +6,15 @@
gzh_search_url = 'http://weixin.sogou.com/weixin?type=1&s_from=input&query&ie=utf8&_sug_=n&_sug_type_=&w=01019900&sut=10144&sst0=1500528877030&lkt=1%2C1500528876895%2C1500528876895&page'
+# test path
+img_base_path = './imgs/'
+
db_config = {
'host': '127.0.0.1', # host
'port': 3306, # port
'user': 'root', # database username
'password': '123456', # database password
- 'db': 'HUANLEYE', # database name
+ 'db': 'DATABASE', # database name
'charset': 'utf8mb4', # database charset
'cursorclass': pymysql.cursors.DictCursor
}
\ No newline at end of file
diff --git a/db.py b/db.py
index 24db695..28d7931 100644
--- a/db.py
+++ b/db.py
@@ -10,15 +10,14 @@
import config
import utils
-from ImgHandler import ImgHandler
-
-img_handler = ImgHandler()
class DB(object):
"""docstring for DB"""
- def __init__(self, db_config, **kwargs):
+ def __init__(self, **kwargs):
super(DB, self).__init__()
- self._db = utils.merge(db_config, (config.db_config))
+ db_config = kwargs.get('db_config')
+ self._db = utils.merge(db_config, config.db_config)
+ print(self._db)
def store_gzh_list(self, gzhList, **kwargs):
if(type(gzhList) != list):
@@ -26,7 +25,7 @@ def store_gzh_list(self, gzhList, **kwargs):
table = kwargs.get('table', 'gzh')
[self._store_gzh_info(i, table=table) for i in gzhList]
- def store_gzh_info(self, info, **kwargs):
+ def _store_gzh_info(self, info, **kwargs):
table = kwargs.get('table')
query = 'insert into ' + table + ' (`title`, `wechatid`, `avatar`, `qrcode`, `introduction`, `verification`) values ("' + info.get('title', '') + '", "' + info.get('wechatid', '') + '", "' + info.get('avatar', '') + '", "' + info.get('qrcode', '') + '", "' + info.get('introduction', '') + '", "' + info.get('verification', '') + '")'
self._execute(query)
@@ -34,30 +33,19 @@ def store_gzh_info(self, info, **kwargs):
def store_article(self, article, **kwargs):
for i in article:
article[i] = self._escape(article[i])
- table = kwargs.get('table', 'article_copy')
+
+ table = kwargs.get('table', 'articles')
query = 'insert into ' + table + ' (`title`, `poster`, `authorId`, `authorAvatar`, `authorName`, `col`, `description`, `content`, `updateTime`, `tag`, `likes`, `type`) values ("' + article.get('title', '') + '", "' + article.get('poster', '') + '", NULL, "' + article.get('authorAvatar', '') + '", "' + article.get('authorName', '') + '", "' + article.get('col', '') + '", "' + article.get('description', '') + '", "' + article.get('content', '').strip() + '", DATE_ADD(\'1970-01-01 00:00:00\', INTERVAL ' + str(article.get('updateTime', '')) + ' SECOND), 0, 0, 0)'
self._execute(query)
print(article['title'] + ' inserted')
- # replace poster or author avatar or all imgs in content
- def replace_imgs(self, imgs, position, **kwargs):
- table = kwargs.get('table', 'articles')
- multi = kwargs.get('multi', False)
- if(multi or type(imgs) == 'list'):
- imgs_copy = imgs[:]
- paths = [img_handler.write_img(img) for img in imgs_copy]
- for i in range(len(paths)):
- self._replace_img(position, path[i], imgs[i], table)
- else:
- path = img_handler.write_img(imgs)
- effect_rows = self._replace_img(position, path, imgs, table)
- return effect_rows
-
def check_exist(self, title, **kwargs):
- query = 'select * from ' + kwargs.get('table', 'article_copy') + ' where title="' + self._escape(title) + '"'
+ print('checking exist')
+ query = 'select * from ' + kwargs.get('table', 'articles') + ' where title="' + self._escape(title) + '"'
effect_rows = self._execute(query)
return effect_rows
+
def _execute(self, query):
conn = pymysql.connect(**self._db)
cursor = conn.cursor()
@@ -65,11 +53,7 @@ def _execute(self, query):
conn.commit()
cursor.close()
conn.close()
- return effect_rows
-
- def _replace_img(self, position, newPath, oldPath, table, **kwargs):
- query = 'update ' + table + ' set ' + position + '=' + newPath + ' where ' + position + '=' + oldPath
- effect_rows = self._execute(query)
+ print('connection closed')
return effect_rows
def _escape(self, string):
@@ -86,4 +70,4 @@ def _escape(self, string):
-
\ No newline at end of file
+
diff --git a/geckodriver b/geckodriver
new file mode 100755
index 0000000..b8d586b
Binary files /dev/null and b/geckodriver differ
diff --git a/main.py b/main.py
index 85e4ed0..73df98f 100644
--- a/main.py
+++ b/main.py
@@ -5,27 +5,40 @@
from WechatScraper import WechatScraper
from db import DB
import utils
+import re
ws = WechatScraper()
-for i in range(3):
- gzh_list = ws.search_gzh_by_keyword('manwei', page=i + 1)
- db.store_gzh_list(gzh_list)
- time.sleep(3)
+'''
+to custom your databse config , add db_config as a named parameter like:
+ db_config = {
+ 'host': '127.0.0.1', # host
+ 'port': 3306, # port
+ 'user': 'root', # database username
+ 'password': '123456', # database password
+ 'db': 'DATABASE', # database name
+ }
+'''
+
+db = DB()
+
+from ImgHandler import ImageHandler
+ih = ImageHandler()
-# scrap 10 page articles related to one keyword
+# scrap 10 page articles related to one keyword.
+# images will be put oin imgs folder
keyword_list = [{
- 'keyword': 'manwei',
+ 'keyword': '漫威',
'page': 10
}, {
- 'keyword': 'marvel',
+ 'keyword': 'DC',
'page': 10
}]
def digest_article(msg, **kwargs):
- col = kwargs.get('col', '过山车')
+ col = kwargs.get('col', 'mycol')
url = msg['url'].replace('amp;', '')
effect_rows = db.check_exist(msg['title'])
if(effect_rows>0):
@@ -34,8 +47,22 @@ def digest_article(msg, **kwargs):
article = ws.get_article_by_url(url)
article = utils.merge(article, msg)
article['col'] = col
+
+ content = article['content']
+ # replace images
+ img_re = re.compile(r']+data\-src\=\"http[^"]+\"')
+ images = img_re.findall(content)
+ for j in range(len(images)):
+ images[j] = re.sub(' 0):
+ article['poster'] = ih.write_image(article['poster'][0])
+ print('article get')
db.store_article(article)
- time.sleep(5)
+ print('article stored')
+ time.sleep(3)
for item in keyword_list:
for i in range(item['page']):
diff --git a/www b/www
new file mode 100644
index 0000000..67954e5
--- /dev/null
+++ b/www
@@ -0,0 +1,2445 @@
+#! /bin/bash
+
+# Google Chrome Installer/Uninstaller for 64-bit RHEL/CentOS 6 or 7
+# (C) Richard K. Lloyd 2017
+# See https://chrome.richardlloyd.org.uk/ for further details.
+
+# Barring bug fixes, this is the final version of the script!
+# Google Chrome 59+ will *not* work on RHEL/CentOS 6, so users
+# on that platform should not upgrade beyond version 58.
+
+# This script is in the public domain and has no warranty.
+# It needs to be run as root because it installs/uninstalls RPMs.
+
+# Minimum system requirements:
+# - 64-bit RHEL/CentOS 6.6 or later (32-bit is no longer supported)
+# (any 64-bit RHEL/CentOS 7 version is supported)
+# - Minimum RHEL/CentOS 6 kernel version supported is 2.6.32-431.el6
+# (any RHEL/CentOS 7 kernel version is supported)
+# - At least 250MB free in each of the temporary directory, /opt and /root
+# - A working yum system (including http proxy configured if needed)
+# - http_proxy and https_proxy env vars set if you are using an http proxy
+# - Google Chrome should not be running at the same time as this script
+
+show_syntax()
+# Show syntax of script
+{
+ cat <<@EOF
+Syntax: ./install_chrome.sh [-b] [-d] [-f [-f [-f]]] [-h] [-n] [-q] [-r] [-s]
+ [-t tmpdir] [-u] [-U]
+
+-b (or --beta) will switch to beta versions (google-chrome-beta).
+-d (or --delete) will delete the temporary directory used for downloads
+ if an installation was successful.
+-f (or --force) forces an automatic "y" for any interactive prompting
+ except for OS mismatch/OS upgrade/reboot prompts. Specify -f twice to force
+ it for OS mismatches or OS upgrades as well and three times for reboots
+ on top of that.
+-h (or -? or --help) will display this syntax message.
+-n (or --dryrun) will show what actions the script will take,
+ but it won't actually perform those actions.
+-q (or --quiet) will switch to "quiet mode" where minimal info is displayed.
+ Specify -q twice to go completely silent except for errors.
+-r (or --re-run) indicates the script is being re-run after an upgrade
+ (internal use only - do not use -r during an initial run of the script).
+-s (or --stable) will switch to stable versions (google-chrome-stable),
+ which is the default if -b or -U haven't previously been specified.
+-t tmpdir (or --tmpdir tmpdir) will use tmpdir as the temporary directory
+ parent tree rather than \$TMPDIR (if set) or /tmp.
+-u performs an uninstallation of Google Chrome and chrome-deps-* rather the
+ default action of an installation.
+-U (or --unstable) will switch to unstable versions (google-chrome-unstable).
+@EOF
+}
+
+# Current version of this script
+version="8.00"
+
+# This script will download/install the following for an installation:
+
+# These RHEL/CentOS 6 RPMs and their (many!) deps that aren't already installed
+# or are out-of-date:
+# redhat-lsb, wget, xdg-utils, GConf2, libXScrnSaver, libX11, gnome-keyring,
+# gcc, glibc-devel, nss, rpm-build, libexif, dbus, selinux-policy, xz
+# and rpmdevtools.
+# These RHEL/CentOS 7 RPMs and their (many!) deps that aren't already installed
+# or are out-of-date:
+# redhat-lsb, wget, xdg-utils, GConf2, libXscrnSaver. libX11, gnome-keyring,
+# libexif, dbus, nss, selinux-policy and xz.
+# The latest Google Chrome RPM if not already downloaded (or out-of-date).
+# RHEL/CentOS 6 only: libstdc++ library from a gcc 6.2.0 source build.
+
+# For RHEL/CentOS 6 only:
+# It then copies the downloaded libstdc++ library into /opt/google/chrome*/lib.
+
+# Next, it C-compiles a shared library that provides the "missing"
+# gnome_keyring_attribute_list_new function that's installed as
+# /opt/google/chrome*/lib/libgnome-keyring.so.0 and linked against a
+# newly installed soft-link called
+# /opt/google/chrome*/lib/link-to-libgmome-keyring.so.0 which in turn points
+# to the system copy of libgmome-keyring.so.0.
+
+# Finally, it creates and installs a chrome-deps-* RPM which includes the
+# downloaded libstdc++ library, libgnome-keyring.so.0, the soft-link
+# link-to-libgmome-keyring.so.0 and code to modify the
+# google-chrome wrapper. (End of RHEL/CentOS 6 only actions)
+
+# Note that you can't run Google Chrome as root - it stops you from doing so.
+
+# Revision history:
+
+# 8.00 - 4th May 2017
+# - Barring bug fixes, this is the final release of the script because
+# Google Chrome 59+ will no longer work on RHEL/CentOS 6.
+# - Changed all 2016 references to 2017.
+# - Moved to gcc 7.1.0 for libstdc++ and bumped chrome-deps version
+# to 4.00 because of that.
+# - If Google Chrome 58 is installed on RHEL/CentOS 6, warn that it's the
+# last major release that works on RHEL/CentOS 6 and that it will be an
+# increasing security risk to run it in the long term.
+# - If version 59+ of Google Chrome is downloadable/installable on RHEL/CentOS 6,
+# refuse to download/install it and delete the Chrome repo file to
+# prevent "yum update" downloading it.
+
+# 7.51 - 22nd December 2016
+# - Superuser now required to run cleanup code in error() function.
+# - A checksum and size has been added to version.dat and this is checked
+# (against the uncompressed version) when an upgraded script is downloaded.
+# - A new gcc 6.3.0 release meant a fresh build of the libstdc++ library
+# and a version bump of the chrome-deps RPM.
+
+# 7.50 - 26th August 2016
+# - If the script is upgraded and re-run, pass a new -r option to avoid a
+# second upgrade, which might have otherwise happened (yes, in a
+# never-ending loop) if the downloaded version.dat file was a cached copy.
+# - xz is now installed/updated early on (prior to any wget-based downloads).
+# - Upgrades now download/decompress install_chrome.sh.xz, only falling
+# back to the uncompressed download if that fails.
+# - Use gcc 6.2.0 as the basis for libstdc++.so.
+# - Web site is now 100% SSL (http requests redirect to the equivalent https),
+# thanks to a new auto-renewing Let's Encrypt secure cert.
+
+# 7.40 - 15th May 2016
+# - If wget isn't installed (e.g. it's a minimal CentOS 6 install) or it's
+# out-of-date, download and install it.
+# - dbus and selinux-policy (if SELinux is enabled) dependencies have been
+# added, which may help minimal installs.
+# - If dbus isn't running on CentOS 6, it's now started and also enabled via
+# chkconfig for future reboots.
+# - If any of the main dependencies are out-of-date, they will now be updated
+# (this is particularly critical for nss and selinux-policy, which won't work
+# on an unpatched 6.7 install).
+
+# 7.31 - 29th April 2016
+# - The Google Chrome binary seems to dynamically load libexif.so.12 at
+# runtime which caused me to miss libexif off the dependencies list, so
+# it's finally been added in.
+# - gcc 6.1.0 is now used as the basis for the libstdc++ download, so that
+# meant a new size and checksum as usual.
+
+# 7.30 - 5th March 2016
+# - Google have completely pulled the 32-bit Linux Google Chrome repository,
+# so I've matched this by dropping 32-bit support (I don't understand
+# why anyone would ever install 32-bit RHEL/CentOS, but that's just me :-) ).
+# - An out-of-date kernel is always an error now rather than a warning.
+
+# 7.24 - 13th February 2016
+# - Adjusted year references to be 2016.
+# - Finally removed all references to LD_PRELOAD.
+# - Warn that this script's 32-bit support is deprecated and will be
+# removed in a future release (shortly after Google Chrome drops 32-bit).
+# - CentoS 7.2.1511 is on the mirrors, so grab 32-bit libstdc++ from that
+# and switch the fallback to the 7.1.1503 version.
+
+# 7.23 - 15th December 2015
+# - Increased version of chrome-deps package to 3.12 because of the newer
+# libstdc++ in the previous release (yes, I should have done that with 7.22).
+# - wget now ignores cached files (e.g. from proxies) when downloading.
+# - If your running kernel is older than 2.6.32-431.el6 and you either refuse
+# (or fail) to update it when prompted or refuse to reboot after the latest
+# kernel update, then this is now a fatal error rather than a warning.
+# - On an unrelated note (the company I work for hosts the official site),
+# good luck to Tim Peake/Principia today - see https://principia.org.uk/
+
+# 7.22 - 12th December 2015
+# - The gcc 5.3.0-built version of 64-bit libstdc++.so.6 is now downloaded,
+# triggering a new script release.
+# - RHEL/CentOS 6.6 is now the mandatory minimum 6.X release this script will
+# run on. If you don't upgrade to at least 6.6 when prompted, the script
+# will abort (previous releases let you continue with a warning).
+#
+# 7.21 - 23rd July 2015
+# - gcc 5.2.0 was recently released, so the downloadable 64-bit libstdc++.so.6
+# was rebuilt using it. A new checksum/size for the library meant a new
+# script release.
+
+# 7.20 - 7th June 2015
+# - Warn about out-of-date kernels that will cause Google Chrome to crash
+# and offer to update the kernel (and preferably reboot).
+# - Fixed a yum repo path typo shown during a dry run (-n) (reported by John
+# Stembridge).
+# - Don't try to create a spec file if the dry run option -n is specified
+# (also reported by John Stembridge).
+# - Removed remove_redundant_libs() function - ironically, it's now redundant.
+
+# 7.13 - 24th April 2015
+# - Updated the downloadable 64-bit libstdc++.so.6 to one built from gcc 5.1.0.
+# Sadly, the uncompressed library has bloated to being 60% bigger than the
+# one created from gcc 4.9.2 :-(
+
+# 7.12 - 10th April 2015
+# - CentOS 7.0.1406 got abruptly shunted off to vault.centos.org this week,
+# promptly completely breaking the 32-bit libstdc++ RPM download. Now the
+# download looks at latest 7.1.1503 RPM on mirror.centos.org first and if
+# that gets moved (which it eventually will be when 7.2 comes out), it looks
+# at the latest 7.0.1406 update on vault.centos.org as a fallback.
+
+# 7.11 - 23rd February 2015
+# - Added a Provides: link to the spec file to avoid RPM dependency issues
+# with the soft-link (thanks to Raymond Page for spotting the issue) and
+# bumped chrome-deps-* RPM version to 3.11.
+
+# 7.10 - 6th February 2015
+# - The later libstdc++ works fine with LD_LIBRARY_PATH pointing to it when
+# sub-processes are run, so we can finally stop using LD_PRELOAD and the
+# unset_var.so shared library.
+# - We still need the "missing" gnome_keyring_attribute_list_new function
+# that's in later releases of libgnome-keyring.so.0, so build a library
+# using that name with the function in it, but link it against a soft-link
+# (link-to-libgnome-keyring.so.0 which soft-links to the system-installed
+# copy of libgnome-keyring.so.0). Convoluted, but allows us to bring in
+# both gnome_keyring_attribute_list_new and all the other library functions/
+# symbols in at start-up.
+# - Added gnome-keyring as a dependency just to make sure it's there before
+# we go ahead with the machinations above.
+# - 50% reduction in orphaned kitten-killing tendencies.
+
+# 7.00 - 2nd February 2015
+# - Raise minimum RHEL/CentOS 6 version required from 6.5 to 6.6. This is
+# because 6.6 now has library updates that negate the need to install patched
+# versions from Fedora 15 or 17.
+# - The only external library that has to remain is libstdc++, which provides
+# the appropriate runtime symbols to satisfy the Google Chrome binary. The
+# good news is that it no longer needs to be patched. For 64-bit systems,
+# the libstdc++ is lifted by me from a gcc 4.9.2 source build I did.
+# For 32-bit systems, libstdc++ is extracted from the CentOS 7 libstdc++ RPM.
+# - If the updated CentOS 7 libstdc++ 32-bit RPM goes "missing" (e.g. it is
+# removed because of an even newer update), fall back to the
+# original 32-bit libstdc++ RPM that shipped with the initial CentOS 7 release.
+# I will release a new script version if a libstdc++ (or gcc source) update
+# happens of course.
+# - Remove any unneeded /opt/google/chrome*/lib libraries that are probably
+# hanging around from earlier script releases. For the avoidance of
+# doubt, this includes removing the F15 libc library, thus removing the
+# GHOST vulnerability that previous script releases may have had.
+# - Use %_topdir for RPM build dir location (thanks to Bob Hepple for this)
+# - Changed year to 2015 in a few places.
+# - Now kills less orphaned kittens than ever!
+
+# 6.10 - 29th August 2014
+# - Don't permanently run 2 copies of cat from the google-chrome script
+# (this is a horrible kludge intro'ed by Google Chrome 37). They both
+# crashed with the previous (6.00) install_chrome.sh, so now just redirect
+# stdout and stderr to /dev/null instead (OK, it'll hide console messages/
+# errors, but that's better than 2 core dumps or, indeed, running 2 cats).
+# - Added "Obsoletes: chrome-deps" to the RPM spec file (suggested by a
+# couple of users).
+# - Bumped both wrapper_mod_version and the chrome-deps RPM to version 2.10.
+
+# 6.00 - 27th July 2014
+# - Google Chrome 36 onwards now has separate install trees for each
+# RPM type (stable, beta, unstable), but bizarrely all 3 RPMs include an
+# /usr/bin/google-chrome soft-link, preventing simultaneous installation.
+# Code was duly added to deal with this significant change.
+# - Added PackageKit as a dependency (some live CentOS DVDs don't install it).
+# - Removed the last remnants of the custom CentOS 7 repo code.
+# - Used a soft-link to fix a failed grep of google-chrome.desktop during the
+# installation of the beta or unstable RPM (this is a Google bug, not mine).
+# - wrapper_mod_version changed to 2.00 and code added to scan for
+# all 3 RPM types since the defaults for all 3 of them are dubiously
+# stuck in a single /etc/default/google-chrome file.
+# - Bumped chrome-deps-* version to 2.00 because check for google-chrome*
+# binary path was widened and the RPM name has changed to include
+# stable, beta or unstable as appropriate.
+# - If an old "chrome-deps" RPM is present during (un)installation, remove it.
+
+# 5.02 - 10th July 2014
+# - Now CentOS 7 final is out, remove the pre-release repo code and
+# delete the .repo file if it was created. Refusing to upgrade the OS to
+# 6.5 or later will now terminate the script rather than continue with a
+# warning. Changed all equivalent RHEL and CentOS references to be
+# RHEL/CentOS instead.
+
+# 5.01 - 26th June 2014
+# - Fix for latest CentOS 7 pre-release repo detection, because the latest
+# pre-release bizarrely includes placeholder .repo files that don't do
+# anything.
+
+# 5.00 - 21st June 2014
+# - Added support for pre-release CentOS 7, which mainly means no RPM building
+# and also the installation of missing dependencies. If no CentOS 7 repos are
+# detected - which is the current case with pre-release CentOS 7 versions -
+# in /etc/yum.repos.d, a "chrome-deps-updates" repo will be created (this
+# will be removed on later runs if any other .repo files are created, on the
+# assumption that the user has added their own repos for installing/updating
+# RPMs instead or the final CentOS 7 repos are already present).
+# - Minimum RHEL/CentOS 6 release supported is now 6.5, which has been out for
+# over 6 months at the time of writing. This means libX11 and nss should be
+# up-to-date versions, avoiding run-time problems with older versions of
+# those packages.
+# - Tidied up final messages e.g. it now says the latest version was already
+# installed if that was the case.
+#
+# 4.70 - 17th May 2014
+# - Added -f option to auto-force a "y" answer to any interactive prompt
+# without bothering to actually prompt you (thanks to Steve Cleveland for the
+# idea). The only exceptions to this are the prompts for an OS mismatch, OS
+# upgrade or reboot, but even those can be forced by specifying -f twice (or
+# three times for reboots).
+# - Fixed the 2-hourly bash segfault recorded in syslog. It was caused by the
+# chrome binary self-calling the google-chrome bash script to get its version,
+# which is bizarre since surely it could just call one of its own functions
+# to get that? By unsetting LD_LIBRARY_PATH on the self-call, the segfault
+# was avoided. Bumped chrome-deps to version 1.21 because of this.
+
+# 4.60 - 12th April 2014
+# - The latest Google Chrome releases kept prompting me for a keyring
+# password when starting up. It turns out they were using the
+# gnome_keyring_attribute_list_new function, which didn't exist until Fedora
+# 17's libgnome-keyring.so.0 library! Luckily, the F17 library works in
+# RHEL/CentOS 6, so that's been added and the chrome-deps RPM has been
+# bumped to version 1.20.
+# - Added nss to the list of possible RHEL/CentOS 6 RPMs that are installed
+# (thanks to Ravi Saive at tecmint.com for this, though no-one told me
+# directly...).
+# - Check the size and cksum of downloaded RPMs and delete them (and quit) if
+# they are bad.
+
+# 4.50 - 11th December 2013
+# - A user reported that file-roller wouldn't work when opening downloaded
+# .tar.gz files inside Google Chrome. It turns out LD_PRELOAD was still set
+# when file-roller tried to exec() sub-processes like gzip, so I now unset
+# LD_PRELOAD (as well as LD_LIBRARY_PATH) when exec'ing from within Google
+# Chrome, which fixes the issue. chrome-deps version was bumped to 1.10
+# because of this change. Another user suggested checking previously
+# downloaded F15 RPMs have the right checksum/size (and a fresh download is
+# forced if they don't), which has been implemented.
+
+# 4.41 - 9th December 2013
+# - Added glibc-devel to the list of dependencies because a user reported
+# that it wasn't dragged in by gcc. With the imminent release of Fedora 20,
+# Fedora 15 has been archived and the code has been changed to reflect that.
+# Removed SELinux warning at end of install - the last few releases of
+# Google Chrome don't seem to have a problem with enforcing mode w.r.t.
+# nacl_helper. Future releases of this script may remove all SELinux-related
+# code if enforcing mode remains OK. Google Chrome 31 is displaying a
+# manifestTypes error to the console in some setups, but this doesn't seem
+# to affect the running of Google Chrome.
+
+# 4.40 - 5th October 2013
+# - A similar issue to the 4.30 release cropped up again (reported by
+# the same user!) that I still can't reproduce. This time it was a missing
+# gdk_pixbuf_format_get_type symbol in F15's libgtk-x11-2.0. This was fixed
+# by additionally downloading F15's gdk-pixbuf2 RPM and extracting
+# libgdk_pixbuf-2.0 from it. This prompted a bump of the chrome-deps RPM to
+# version 1.03.
+
+# 4.30 - 4th October 2013
+# - The g_desktop_app_info_get_filename symbol in the F15 libgdk-x11-2.0
+# library is present in the F15 libgio-2.0 library (but not in RHEL/CentOS's).
+# The script used the former library, but not the latter and a user reported
+# a missing symbol crash due to this, despite my testing not showing the
+# issue. This release is therefore purely to add libgio-2.0 and its
+# libgobject-2.0 dependency to the set of extracted F15 libraries and has
+# also been tested against Google Chrome 30 and Google Talk Plugin 4.7.0.0.
+# The chrome-deps RPM is now at version 1.02 because of the two extra
+# libraries.
+
+# 4.20 - 22nd August 2013
+# - If the Google Chrome repo is enabled and a Google Chrome RPM is already
+# installed, use "yum check-update google-chrome-stable" to determine if
+# there is a newer version available and then fallback to using the
+# OmahaProxy site if there isn't.
+# - Any newer version than what's been previously downloaded or installed
+# can now be downloaded/installed, rather than being exactly the version
+# displayed on the OmahaProxy site (which was out of date for a full day when
+# Chrome 29 was released, stopping this script from updating to version 29).
+# - Removed terminal messages warning because this is fixed with Google Chrome
+# 29.
+# - Used extra parameters in the OmahaProxy request to narrow the data down to
+# the exact channel and platform (linux).
+
+# 4.10 - 8th August 2013
+# - Fixed Google Talk (Hangouts) plugin crash - it was because, unlike Google
+# Chrome itself, the plugin hasn't been built with later libraries, so it
+# needs LD_LIBRARY_PATH to be unset. There still appears to be other
+# library issues with the Hangouts plugin, mainly because the older libraries
+# don't implement certain calls it uses. Google need to update the plugin!
+# Bumped chrome-deps version to 1.01 because of the unset_var.c change.
+# - Catered for non-standard i686 RPM build trees on 32-bit systems. I couldn't
+# reproduce this myself (it uses i386 for me all the time in RHEL/CentOS and
+# Scientific Linux 32-bit VMs) but the code is in place anyway for the users
+# that reported the issue.
+# - modify_wrapper (now bumped to version 1.01) no longer echoes anything to
+# stdout after a successful update of /opt/google/chrome/google-chrome.
+
+# 4.01 - 30th July 2013
+# - Emergency 2-char change fix due to a terrible spec parsing bug in rpmbuild.
+# It appears that it tries to parse % directives in comment lines.
+# Strangely, three different build envs of mine didn't have the bug, but
+# a fourth one I tried did.
+#
+# 4.00 - 30th July 2013
+# - Creates a new chrome-deps RPM that it installs alongside the
+# google-chrome-stable RPM. It contains the Fedora libraries, the
+# built unset_var.so library and a script which is run post-install
+# to add code to /etc/default/google-chrome to modify google-chrome if
+# its LD_PRELOAD addition isn't present. This gets sourced daily by
+# /etc/cron.daily/google-chrome and is a way to auto-modify google-chrome
+# within a day of a Google Chrome update (this is because google-chrome
+# isn't marked as a config file by Google Chrome's spec file, so updates
+# will overwrite any changes made to it). The new code will also enable the
+# Google Chrome repo of course. Many thanks to Marcus Sandberg
+# for his spec file at https://github.com/adamel/chrome-deps which
+# I used as the initial basis for the spec file I create.
+# - Adjusted unset_var code to not unset LD_LIBRARY_PATH if a full file
+# path (i.e. one containing a slash) is supplied to exec*() routines.
+# - Download/installation of google-chrome-stable/chrome-deps dependencies
+# is now prompted for (if you decline, the script aborts).
+# - Moved out-of-date OS check right to the end of the script and it also
+# now offers to reboot the machine after a successful OS update. Warn user
+# not to run Google Chrome if either the OS update or reboot are declined
+# until they complete the OS update and reboot.
+# - Don't remove /etc/cron.daily/google-chrome or
+# /etc/yum.repos.d/google-chrome.repo any more because we actually want
+# people to use those (they won't be happy cron'ing this script or having
+# to regularly run it manually to check for updates).
+# - Added -t option to specify the temporary directory parent tree.
+# - Added -s (stable), -b (beta) and -U (unstable) options to switch
+# release channels. Yes, it remembers the switch, so you only have to
+# specify once time.
+# - Added libdl.so.2 to the Fedora library list (for unset_var.so).
+
+# 3.20 - 27th July 2013
+# - Initial attempt to stop helper apps crashing by wrapping exec*() routines
+# with LD_PRELOAD functions that save/blank LD_LIBRARY_PATH, call the
+# original routines and, if they return, restore LD_LIBRARY_PATH. Seems to
+# stop crashes previously logged to syslog on startup at least, but does
+# require gcc and its dependencies to be installed now of course.
+
+# 3.11 - 25th July 2013
+# - If SELinux is enabled, set appropriate SELinux contexts on Fedora libraries
+# in /opt/google/chrome/lib and that directory itself. Investigation shows
+# that if you enable SELinux and set it to enforcing, nacl_helper appears to
+# fail to start correctly, possibly disabling sandboxing. The script warns
+# about this and suggests a temporary workaround of setting
+# SELINUX=permissive in /etc/selinux/config and rebooting. It's hoped to fix
+# this SELinux issue more permanently in a future release soon (any help is
+# most welcome!).
+
+# 3.10 - 24th July 2013
+# - Use .so.0 extension (instead of .so.3) for renamed Fedora ld-linux library
+# and change ld-linux*.so.2 references to ld-linux*.so.0 in ld-linux, libc
+# and libstdc++. Thanks to Marcus Sundberg for this suggestion.
+# - Dependency list for Google Chrome RPM is now redhat-lsb, wget, xdg-utils,
+# GConf2, libXScrnSaver and libX11 (not 1.3* or 1.4* though).
+# - If OS version ("lsb_release -rs") is less than 6.4 then
+# offer to "yum update" and refuse to continue if the user declines.
+# If you don't update to at least 6.4, bad things can
+# happen (I got a hang and a memory allocation error when starting Google
+# Chrome on a RHEL/CentOS 6.0 VM for example).
+
+# 3.00 - 21st July 2013
+# - Command-line options now supported including -d (delete temp dir),
+# -h (syntax help), -n (dry run), -q (quiet) and -u (uninstall).
+# - Abort if Google Chrome is running when the script is started.
+# - Display any non-zero disk space figures for /opt/google/chrome and the
+# temporary download directory at the start and end of the script.
+
+# 2.10 - 20th July 2013
+# - Can now detect if Fedora 15 RPMs have been archived and will download
+# them from the archive site if they're found there instead.
+# - Fixed lsb package check, so lsb deps will actually be downloaded now.
+# - Follow Fedora 15 library soft-links to determine the actual filenames
+# that need to be copied.
+# - Removed /etc/cron.daily/google-chrome and
+# /etc/yum.repos.d/google-chrome.repo straight after the Google Chrome RPM
+# is installed to avoid any potential conflict with old releases.
+# - Simplistic check for RHEL/CentOS 6 derivatives (initially a prompt if the
+# script thinks you aren't running one, but a future release will block
+# non-derivatives).
+# - Early exits due to errors or an interrupt (CTRL-C) will now properly
+# tidy up files in the temporary directory and uninstall the Google Chrome
+# RPM if it was installed.
+# - All downloads now go via a common function, which saves any pre-existing
+# file as a .old version and renames it back if the download fails.
+
+# 2.00 - 14th July 2013
+# - Installed a 32-bit RHEL/CentOS 6.4 VM and this enabled me to add initial
+# 32-bit support, though there is an nacl_helper issue that I display a warning
+# for. Thanks to Seva Epsteyn for a 32-bit patch that got the ball rolling.
+# - Check for version number of latest Google Chrome and download/install it
+# if it hasn't been already.
+# - Use updated Fedora 15 RPMs rather than the original ISO versions.
+# - Warn if an enabled Google Chrome repo is detected (we don't want it).
+# - Tidied main code into separate functions.
+# - Added blank lines before/after messages and prefixed them with three stars.
+# - Displayed more messages now they're easier to read.
+
+# 1.10 - 13th July 2013
+# - Added an update check for a new version of this script.
+# It will always download/install the new version, but will ask
+# if you want to run the new version or exit in case you want to
+# code inspect it first.
+# - Always force-install a downloaded Google RPM, even if a version
+# is already installed. Yes, very obvious it should do this but it
+# didn't (slaps forehead).
+
+# 1.02 - 13th July 2013
+# - Second emergency fix today as someone spotted that wget needed
+# "--no-check-certificate" to talk to Google's https download site.
+# I didn't need it for the two machines I tested it on though!
+# - Added in a check for wget as well while I was at it and it will
+# yum install wget if it's not found.
+
+# 1.01 - 13th July 2013
+# - Bad variable fix if you've not downloaded Google Chrome's RPM yet.
+# Serves me right for making a last minute change and not testing it :-(
+
+# 1.00 - 13th July 2013
+# - Tested on 64-bit RHEL/CentOS 6.4 using Fedora 15 libraries. Code is there
+# for 32-bit but has not been tested at all because I have no such systems.
+
+message_blank_line()
+# $1 != "n" (and no quiet mode) to display blank line
+{
+ if [ $quiet -eq 0 -a "$1" != "n" ]
+ then
+ echo
+ fi
+}
+
+message_output()
+# Display $1 depending on the quiet mode
+{
+ case "$quiet" in
+ 0) echo "*** $1 ..." ;;
+ 1) echo "$1" ;;
+ esac
+}
+
+message()
+# Display a message (passed in $1) prominently
+# $2 = "n" to avoid displaying blank lines before or after the message
+{
+ if [ $quiet -eq 2 ]
+ then
+ return
+ fi
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would display the following message:"
+ message_output "$1"
+ echo
+ return
+ fi
+
+ message_blank_line "$2"
+ message_output "$1"
+ message_blank_line "$2"
+}
+
+warning()
+# $1 = Warning message to display to stderr
+# $2 = "n" to avoid displaying blank lines before or after the message
+{
+ message "WARNING: $1" "$2" >&2
+}
+
+show_space_used()
+# Calculate disk space and number of files in install and temp dirs
+# and display it if there actually any installed files
+{
+ for each_tree in "$inst_tree" "$tmp_tree"
+ do
+ if [ -d "$each_tree" ]
+ then
+ num_files="`find \"$each_tree/.\" -type f | wc -l`"
+ if [ $num_files -gt 0 ]
+ then
+ size_files="`du -s \"$each_tree/.\" | awk '{ printf(\"%d\",$1/1024); }'`"
+ message "$each_tree tree contains $num_files files totalling $size_files MB" "n"
+ fi
+ fi
+ done
+}
+
+clean_up()
+# Remove the stuff we don't want to keep once script finishes
+{
+ # Make sure we don't trash system directories!
+ if [ "$tmp_tree" != "" -a "$tmp_tree" != "/" -a "$tmp_tree" != "/tmp" ]
+ then
+ if [ $delete_tmp -eq 1 ]
+ then
+ if [ -d "$tmp_tree" ]
+ then
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would delete temporary dir $tmp_tree"
+ echo
+ else
+ cd /
+ rm -rf "$tmp_tree"
+ if [ -d "$tmp_tree" ]
+ then
+ warning "Failed to delete temporary directory $tmp_tree"
+ else
+ message "Deleted temporary directory $tmp_tree"
+ fi
+ fi
+ fi
+ else
+ rm_dir_list="etc lib lib64 usr sbin usr var `basename $tmp_updates`"
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would delete these directories/files from inside of $tmp_tree:"
+ echo "$rm_dir_list"
+ else
+ # We delete specific directories/files so that RPM downloads/builds
+ # remain and can be re-used if the script is run again
+ for each_dir in $rm_dir_list
+ do
+ rm -rf "$tmp_tree/$each_dir"
+ done
+ fi
+ fi
+
+ show_space_used
+ fi
+}
+
+is_installed()
+# See if $1 package is installed (returns non-null string if it is)
+{
+ rpm -q "$1" | egrep "($rpmarch|$arch|noarch)" | grep "^$1"
+}
+
+uninstall_rpms()
+# Uninstall $* RPMs if they are installed
+{
+ uninstall_list=""
+ for each_pack in $*
+ do
+ if [ "`is_installed $each_pack`" != "" ]
+ then
+ uninstall_list="$uninstall_list $each_pack"
+ fi
+ done
+
+ if [ "$uninstall_list" != "" ]
+ then
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would uninstall $uninstall_list using \"yum $yum_options remove\""
+ echo
+ else
+ message "Uninstalling $uninstall_list"
+ yum $yum_options remove $uninstall_list
+ fi
+ fi
+}
+
+uninstall_google_chrome()
+# Uninstall the Google Chrome and chrome-deps-* RPMs if they are installed
+{
+ # Remove bug fix soft-link if necessary
+ if [ "$rpm_type" != "stable" -a -h $chrome_desktop ]
+ then
+ rm -f $chrome_desktop
+ fi
+
+ # Note we use the old name in addition, in case it's still installed
+ uninstall_rpms $rpm_name $deps_name
+
+ # Do a final cleanup if /opt/google/chrome* persists
+ if [ "$inst_tree" != "" -a "$inst_tree" != "/" -a "$inst_tree" != "/tmp" ]
+ then
+ if [ -d "$inst_tree" -a $dry_run -eq 0 ]
+ then
+ warning "$inst_tree install tree still present - deleting it" "n"
+ cd /
+ rm -rf "$inst_tree"
+ if [ -d "$inst_tree" ]
+ then
+ warning "Failed to delete $inst_tree install tree" "n"
+ fi
+ fi
+ fi
+}
+
+error()
+# $1 = Error message
+# Exit script after displaying error message
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would display this error message to stderr:"
+ echo "ERROR: $1 - aborted"
+ else
+ echo >&2
+ echo "ERROR: $1 - aborted" >&2
+ echo >&2
+ fi
+
+ # Only uninstall/clean up if the superuser
+ if [ `id -u` -eq 0 ]
+ then
+ # A failure means we have to uninstall Google Chrome
+ # if it got on the system and we were installing, but only
+ # if we got past the check that it was running
+ if [ $do_install -eq 1 -a $past_run_check -eq 1 ]
+ then
+ uninstall_google_chrome
+ fi
+
+ clean_up
+ fi
+
+ exit 1
+}
+
+interrupt()
+# Interrupt received (usually CTRL-C)
+{
+ error "Interrupt (usually CTRL-C) received"
+}
+
+set_tmp_tree()
+# Set tmp_tree variable to $1/chrome_install
+{
+ if [ "$1" = "" -o "$1" = "/" -o "`echo \"x$1\" | grep ^x-`" != "" ]
+ then
+ error "Invalid temporary directory parent specified ($1)"
+ fi
+
+ if [ ! -d "$1" ]
+ then
+ warning "Temporary directory parent $1 doesn't exist - will be created"
+ fi
+
+ tmp_tree="$1/chrome_install"
+ customsrc="$tmp_tree/missing_functions.c"
+ tmp_updates="$tmp_tree/updates.dat$$"
+}
+
+check_binary_not_running()
+# See if the Google Chrome binary is running and abort if it is
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would check to see if $chrome_name is running and abort if it is."
+ echo
+ else
+ if [ "`ps -ef | grep \"$inst_tree/chrome\" | grep -v grep`" != "" ]
+ then
+ error "$chrome_name is running - exit it then re-run this script"
+ fi
+ fi
+ past_run_check=1
+}
+
+yesno()
+# $1 = Message prompt
+# $2 = Minimal force level required (1 if not stated)
+# Returns ans=0 for no, ans=1 for yes
+{
+ ans=1
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would be asked here if you wanted to"
+ echo "$1 (y/n - y is assumed)"
+ else
+ if [ "$2" = "" ]
+ then
+ minforce=1
+ else
+ minforce=$2
+ fi
+
+ if [ $force -lt $minforce ]
+ then
+ ans=2
+ fi
+ fi
+
+ while [ $ans -eq 2 ]
+ do
+ echo -n "Do you want to $1 (y/n) ?" ; read reply
+ case "$reply" in
+ Y*|y*) ans=1 ;;
+ N*|n*) ans=0 ;;
+ *) echo "Please answer y or n" ;;
+ esac
+ done
+}
+
+set_rpm_type()
+# Set RPM type to $1
+# $1 = stable, beta or unstable
+{
+ if [ $do_install -eq 1 -a "$1" != "$old_rpm_type" ]
+ then
+ case "$1" in
+ stable|beta|unstable)
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would prompt to confirm switch to $1 channel"
+ echo "(assuming y is input)"
+ echo
+ else
+ warning "You have requested to switch to the $1 channel"
+ if [ $quiet -eq 0 ]
+ then
+ echo "This script will uninstall all previously installed $chrome_name"
+ echo "packages that originated from non-$1 channels."
+ echo
+ fi
+ yesno "install the $1 release"
+ if [ $ans -eq 0 ]
+ then
+ error "Did not switch to the $1 channel"
+ fi
+ fi ;;
+ *) error "Invalid $chrome_name channel ($1)" ;;
+ esac
+
+ check_binary_not_running
+ uninstall_rpms \
+ `echo google-chrome-stable google-chrome-beta google-chrome-unstable \
+ chrome-deps-stable chrome-deps-beta chrome-deps-unstable | \
+ sed -e "s/google-chrome-$1//g" -e "s/chrome-deps-$1//g"`
+ fi
+
+ case "$1" in
+ stable|beta|unstable)
+ rpm_type="$1"
+ case "$1" in
+ unstable) csv_type="dev" ;;
+ *) csv_type="$1" ;;
+ esac
+ rpm_name="google-chrome-$1"
+ chrome_csv="http://omahaproxy.appspot.com/all?os=linux&channel=$csv_type"
+ chrome_rpm="${rpm_name}_current_$rpmarch.rpm" ;;
+ *) error "Invalid $chrome_name type ($1)" ;;
+ esac
+
+ case "$1" in
+ beta|unstable) swtype="chrome-$1" ;;
+ *) swtype="chrome" ;;
+ esac
+ inst_tree="/opt/google/$swtype"
+ libdir="$inst_tree/lib"
+ missinglib="libgnome-keyring.so.0"
+ customlib="$libdir/$missinglib"
+ customlink="$libdir/link-to-${missinglib}"
+ chrome_wrapper="$inst_tree/google-$swtype"
+ modify_wrapper="$inst_tree/modify_wrapper"
+ this_desktop="$app_tree/google-$swtype.desktop"
+ deps_name="chrome-deps-$rpm_type"
+ deps_latest="`is_installed $deps_name | grep $deps_version`"
+}
+
+init_vars()
+# Initialise variables
+# $1 = Original $0 (i.e. script name)
+{
+ # Set option variables to temporary values so that errors prior to the
+ # actual option parsing behave sensibly
+ dry_run=0 ; do_install=0 ; delete_tmp=0
+ past_run_check=0 ; force=0 ; quiet=0
+
+ # Avoid picking up the custom libs for any binaries
+ # run by this script
+ unset LD_LIBRARY_PATH
+
+ if [ "$TMPDIR" = "" ]
+ then
+ set_tmp_tree "/tmp"
+ else
+ set_tmp_tree "$TMPDIR"
+ fi
+
+ arch="`uname -m`"
+ case "$arch" in
+ x86_64) rellib="lib64" ; rpmarch="$arch"
+ rpmdep="()(64bit)" ;;
+ *) error "Unsupported architecture ($arch)" ;;
+ esac
+ relusrlib="usr/$rellib"
+
+ chrome_name="Google Chrome"
+ # The next definition (chrome_defaults) should probably be different for
+ # stable vs. others, but Google haven't changed it because it's not
+ # shipped with the RPM, but actually created during installation.
+ chrome_defaults="/etc/default/google-chrome"
+ chrome_repo="/etc/yum.repos.d/google-chrome.repo"
+ app_tree="/usr/share/applications"
+ chrome_desktop="$app_tree/google-chrome.desktop"
+ deps_version="4.00"
+ download_lib="libstdc++.so.6"
+ download_lib_xz="$download_lib.xz"
+
+ # Don't get clever and increase good_version to try to install a
+ # version 59+ Google Chrome - you'll just break the browser and
+ # it'll all end in tears with no way to downgrade again!
+ good_version=58 # Last good version - do NOT edit this
+ let bad_version=$good_version+1
+ bad_version="$chrome_name ${bad_version}+"
+
+ # Find the most stable installed Google Chrome and use that
+ # as the default for the rest of the script (override with -b, -s or -U)
+ old_rpm_type=""
+ for each_old_rpm_type in stable beta unstable
+ do
+ if [ "$old_rpm_type" = "" ]
+ then
+ if [ "`is_installed google-chrome-$each_old_rpm_type`" != "" ]
+ then
+ old_rpm_type="$each_old_rpm_type"
+ fi
+ fi
+ done
+
+ # If nothing installed at all, default to stable
+ if [ "$old_rpm_type" = "" ]
+ then
+ old_rpm_type="stable"
+ fi
+ set_rpm_type "$old_rpm_type"
+
+ wrapper_mod_version="2.10"
+ install_message="already installed"
+ trap "interrupt" 1 2 3
+
+ wget="/usr/bin/wget"
+ wget_options="--no-check-certificate --no-cache"
+ yum_options="-y"
+ rpm_options="-U --force --nodeps"
+ chcon_options="-u system_u"
+ rpmbuild_options="-bb"
+
+ # Update checker URL
+ checksite="https://chrome.richardlloyd.org.uk/"
+ checkfile="version.dat"
+ checkurl="$checksite$checkfile"
+ scriptname="install_chrome.sh"
+ upgradeurl="$checksite$scriptname"
+
+ script="$1"
+ case "$script" in
+ ./*) script="`pwd`/`basename $script`" ;;
+ /*) script="$script" ;;
+ *) script="`pwd`/$script" ;;
+ esac
+}
+
+download_file()
+# $1 = Full URL to download
+# $2 = Optional basename to save to (if omitted, then = basename $1)
+# Also allow download to silently fail without exit if $2 is set
+# $3 = Optional cksum value to compare download against
+# $4 = Optional 0 if failures are warnings, = 1 if errors
+# Returns bad_download=0 for success, = 1 for failure
+{
+ bad_download=0
+ if [ "$2" = "" ]
+ then
+ dlbase="`basename \"$1\"`"
+ else
+ dlbase="$2"
+ fi
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would download this URL to $tmp_tree/$dlbase :"
+ echo $1 ; echo
+ return
+ fi
+
+ old_dlbase="$dlbase.old"
+ if [ -f "$dlbase" ]
+ then
+ if [ "$3" != "" ]
+ then
+ # If file already exists with right cksum, do nothing
+ if [ "`cksum \"$dlbase\"`" = "$3" ]
+ then
+ return
+ fi
+ fi
+ rm -f "$old_dlbase"
+ mv -f "$dlbase" "$old_dlbase"
+ fi
+
+ message "Downloading $dlbase (please wait)"
+ $wget $wget_options -O "$dlbase" "$1"
+
+ if [ -s "$dlbase" -a "$3" != "" ]
+ then
+ if [ "`cksum \"$dlbase\"`" != "$3" ]
+ then
+ rm -f "$dlbase"
+ warning "Deleted downloaded $dlbase - checksum or size incorrect"
+ fi
+ fi
+
+ if [ ! -s "$dlbase" ]
+ then
+ bad_download=1
+ if [ -f "$old_dlbase" ]
+ then
+ mv -f "$old_dlbase" "$dlbase"
+ fi
+ if [ "$2" = "" -o "$3" != "" ]
+ then
+ if [ "$4" = "0" ]
+ then
+ warning "Failed to download $dlbase correctly"
+ else
+ error "Failed to download $dlbase correctly"
+ fi
+ fi
+ fi
+}
+
+change_se_context()
+# $1 = File or directory name
+# Change SELinux context type for $1 to lib_t (or other
+# types depending on its name)
+{
+ if [ $selinux_enabled -eq 0 ]
+ then
+ # chcon commands fail if SELinux is disabled
+ return
+ fi
+
+ if [ -s "$1" -o -d "$1" ]
+ then
+ case "$1" in
+ $chrome_wrapper) con_type="execmem_exec_t" ;;
+ $customlib) con_type="textrel_shlib_t" ;;
+ *) con_type="lib_t" ;;
+ esac
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would change SELinux context type of $1 to $con_type"
+ echo
+ else
+ chcon $chcon_options -t $con_type "$1"
+ fi
+ else
+ if [ $dry_run -eq 0 ]
+ then
+ error "Couldn't change SELinux context type of $1 - not found"
+ fi
+ fi
+}
+
+install_custom_lib()
+# Compile and install missing function lib as $libdir/libgnome-keyring.so.0
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would compile/install $customlib"
+ echo
+ return
+ fi
+
+ cat <<@EOF >"$customsrc"
+/* missing_functions.c 3.00 (C) Richard K. Lloyd 2017
+
+ Provides a gnome_keyring_attribute_list_new() function (was
+ a macro in CentOS 6 causing a missing symbol error when Google Chrome
+ was started up) that's present in later libgnome-keyring libraries.
+ See: https://mail.gnome.org/archives/commits-list/2012-January/msg08007.html
+*/
+
+/* Providing the "missing" gnome_keyring_attribute_list_new function
+ -----------------------------------------------------------------
+ To avoid having to install various *-devel packages, the required
+ definitions in CentOS 6.6 headers have been simplified to avoid the
+ need for any include files. I have also added the string "Custom" to the end
+ of any definitions that may clash with the original CentOS 6 libraries.
+*/
+
+/* Simplifying glib/gtypes.h, glib/garray.h and gnome-keyring.h,
+ we get this: */
+struct GnomeKeyringAttributeListCustom
+{
+ char *data;
+ int len;
+};
+
+/* Simplifying glib/gtypes.h and glib/garray.h, we get this: */
+struct GnomeKeyringAttributeListCustom *
+g_array_new (int zero_terminated, int clear_, unsigned int element_size);
+
+/* This is straight from gnome-keyring.h: */
+typedef enum {
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32
+} GnomeKeyringAttributeTypeCustom;
+
+/* Simplifying glib/gtypes.h and gnome-keyring.h, we get this: */
+typedef struct {
+ char *name;
+ GnomeKeyringAttributeTypeCustom type;
+ union {
+ char *string;
+ unsigned int integer;
+ } value;
+} GnomeKeyringAttributeCustom;
+
+/* The "missing" function from CentOS 6's gnome-keyring library */
+struct GnomeKeyringAttributeListCustom *
+gnome_keyring_attribute_list_new (void)
+{
+ return g_array_new (0, 0, sizeof (GnomeKeyringAttributeCustom));
+}
+@EOF
+ if [ -s "$customsrc" ]
+ then
+ rm -f "$customlink" "$customlib"
+
+ # Compile 1: Create the library as the link name.
+ # You could probably copy any old system library
+ # in as $customlink to be honest :-)
+ gcc -O -fpic -shared -s -o "$customlink" "$customsrc"
+ if [ ! -s "$customlink" ]
+ then
+ error "Failed to compile $customlink library"
+ fi
+
+ # Compile 2: Create the library as the system name and link
+ # against the link name
+ gcc -O -fpic -shared -s -o "$customlib" "$customsrc" "$customlink"
+ if [ ! -s "$customlib" ]
+ then
+ error "Failed to compile $customlib library"
+ fi
+
+ # Now remove the link name library/source file and replace the library
+ # with a soft-link to the system library. Now we have $customlib with
+ # the single function that will also load in the system library. It
+ # Would have been easier if there was a built libgnome-keyring.a
+ rm -f "$customlink" "$customsrc"
+ ln -sf "/$relusrlib/$missinglib" "$customlink"
+
+ if [ -h "$customlink" ]
+ then
+ chmod a+rx "$customlib"
+ change_se_context "$customlib"
+ message "Compiled/installed $customlib"
+ else
+ error "Failed to create $customlink soft-link"
+ fi
+ else
+ error "Unable to create $customsrc source file"
+ fi
+}
+
+check_version()
+# Make sure that we are running the latest version
+# $* = Params passed to script
+{
+ # If we're running an upgraded script, -r will have been passed
+ # and we don't need a second upgrade
+ if [ $re_run -eq 1 ]
+ then
+ return
+ fi
+
+ message "Checking for an update to $scriptname" "n"
+ download_file "$checkurl"
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would check if this running script (version $version) is out of date."
+ echo "If it's been superseded, the new version would be downloaded and you'd be asked"
+ echo "if you want to upgrade to it and run the new version."
+ echo
+ return
+ fi
+
+ newversionstr="`cat \"$checkfile\"`"
+ newversion="`echo $newversionstr | awk '{ print $1; }'`"
+ newcksum="`echo $newversionstr | awk '{ print $2; }'`"
+ newsize="`echo $newversionstr | awk '{ print $3; }'`"
+ rm -f "$checkfile"
+
+ if [ "$newversion" = "$version" ]
+ then
+ message "$scriptname is already the latest version ($version) - continuing" "n"
+ else
+ message "New version ($newversion) of $scriptname detected - downloading it now"
+
+ download_file "$upgradeurl.xz" "" "" 0
+ if [ $bad_download -eq 0 ]
+ then
+ xzcat -f "$dlbase" >$scriptname 2>/dev/null
+ if [ $? -ne 0 -o ! -s $scriptname ]
+ then
+ # Corrupted compressed download, delete it and try uncompressed one
+ rm -f "$dlbase" "$scriptname"
+ download_file "$upgradeurl"
+ fi
+ else
+ # If compressed version didn't download, try uncompressed one
+ download_file "$upgradeurl"
+ fi
+
+ if [ "$newcksum" != "" -a "$newsize" != "" ]
+ then
+ if [ "`cksum \"$scriptname\"`" != "$newcksum $newsize $scriptname" ]
+ then
+ rm -f "$scriptname"
+ error "Download of $scriptname $newversion failed (bad checksum)"
+ fi
+ fi
+
+ if [ "$scriptname" -ef "$script" ]
+ then
+ let a=1
+ else
+ mv -f "$scriptname" "$script"
+ fi
+ chmod u+x "$script"
+ message "Download of $scriptname $newversion successful"
+
+ yesno "run $scriptname $newversion now"
+ if [ $ans -eq 1 ]
+ then
+ message "OK, executing $script $* -r"
+ exec "$script" $* -r
+ error "Failed to run $script $* -r"
+ else
+ if [ $quiet -lt 2 ]
+ then
+ echo
+ echo "$scriptname $newversion is available as $script"
+ echo "Please inspect the new code and then run the new script."
+ echo
+ fi
+ clean_up
+ exit 1
+ fi
+ fi
+}
+
+find_latest_chrome_version()
+# Look on OmahaProxy CSV site or in yum repo for latest version number of linux/$csv_type/current
+{
+ message "Determining latest $chrome_name version number (please wait)" "n"
+ chrome_latest=""
+
+ # Do we have a Google Chrome RPM already installed and also
+ # an enabled yum repo for it too?
+ if [ "$chrome_installed" != "" -a "`yum repolist google-chrome enabled | grep ^google-chrome`" != "" ]
+ then
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would use yum check-update to determine if there was a later $chrome_name available."
+ echo
+ return
+ fi
+
+ # We have an enabled repo, do use check-update option to look for an update
+ chrome_latest="`yum check-update google-chrome-$rpm_type | grep ^google-chrome-$rpm_type |
+ awk '{ print $2; }' | cut -d- -f1`"
+ fi
+
+ if [ "$chrome_latest" = "" ]
+ then
+ # No repo update, so now use OmahaProxy's current CSV to find latest version
+ csv_name="chrome_versions.csv"
+ download_file "$chrome_csv" "$csv_name"
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would use OmahaProxy current CSV to determine latest $chrome_name version number"
+ echo
+ return
+ fi
+
+ if [ -s "$csv_name" ]
+ then
+ chrome_latest="`grep ^linux,$csv_type, \"$csv_name\" | head -1 | cut -d, -f3`"
+ fi
+ rm -f "$csv_name"
+ fi
+
+ if [ "$chrome_latest" = "" ]
+ then
+ warning "Unable to determine latest $chrome_name version number" "n"
+ else
+ message "Latest $rpm_name version number is $chrome_latest" "n"
+ if [ $centos -eq 6 ]
+ then
+ case "$chrome_latest" in
+ ${good_version}.*)
+ warning "$chrome_name $good_version is the last major release that will work on RHEL/CentOS $centos" ;;
+ *) for eachrepo in google-chrome google-chrome-beta google-chrome-unstable
+ do
+ fullrepo=/etc/yum.repos.d/$eachrepo.repo
+ if [ -s $fullrepo ]
+ then
+ rm -f $fullrepo
+ message "Deleted $fullrepo to prevent future updates" "n"
+ fi
+ done
+ error "Sorry, but $bad_version won't work on RHEL/CentOS $centos" ;;
+ esac
+ fi
+ chrome_name="$chrome_name $chrome_latest"
+ fi
+}
+
+final_warning()
+# On RHEL/CentOS 6, warn that Google Chrome 58 is the end of the road
+# and running it long term isn't a good idea for security reasons
+{
+ if [ "$chrome_installed" != "" -a $centos -eq 6 ]
+ then
+ case "$chrome_installed" in
+ ${good_version}.*)
+ warning "Google Chrome $good_version is the last major version that will work on RHEL/CentOS $centos" "n"
+ warning "Running it long term will become an increasing security risk!" "n" ;;
+ esac
+ fi
+}
+
+get_installed_version()
+# Find out what version of Google Chrome is installed
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would use \"$chrome_wrapper --version\" or"
+ echo "\"rpm -q $rpm_name\" to determine installed Google Chrome version"
+ echo
+ return
+ fi
+
+ # Look for the installed RPM first and get version from that
+ chrome_installed="`is_installed $rpm_name | cut -d- -f4`"
+
+ # If RPM not installed, see if we can use the shell wrapper for the version
+ if [ "$chrome_installed" = "" -a -x "$chrome_wrapper" ]
+ then
+ # This may fail of course if Google Chrome 28+ installed without custom libstdc++
+ chrome_installed="`\"$chrome_wrapper\" --version 2>/dev/null | awk '{ print $3; }'`"
+ fi
+
+ final_warning
+}
+
+get_downloaded_version()
+# Find out what version of Google Chrome RPM was downloaded
+{
+ if [ $dry_run -eq 1 ]
+ then
+ chrome_downloaded=""
+ echo "Would use \"rpm -qp\" on downloaded Google Chrome RPM to find its version"
+ echo
+ return
+ fi
+
+ if [ -s $chrome_rpm ]
+ then
+ chrome_downloaded="`rpm -qp \"$chrome_rpm\" | cut -d- -f4`"
+ if [ "$chrome_downloaded" = "" ]
+ then
+ error "Can't find version number of $chrome_rpm"
+ fi
+ else
+ chrome_downloaded=""
+ fi
+}
+
+download_chrome_rpm()
+# Download latest RPM because we don't have it downloaded and don't have
+# the latest release installed either
+{
+ download_file "https://dl.google.com/linux/direct/$chrome_rpm"
+ get_downloaded_version
+
+ if [ $dry_run -eq 1 ]
+ then
+ return
+ fi
+
+ if [ "$chrome_latest" = "" ]
+ then
+ chrome_latest="$chrome_downloaded"
+ fi
+
+ if [ "$chrome_downloaded" != "$chrome_latest" ]
+ then
+ # Downloaded version is different from what OmahaProxy claims is
+ # the latest version, so we need to compare the four dot-separated
+ # fields of the version numbers to judge which is the higher.
+ dotfield=1
+ while [ $dotfield -le 4 ]
+ do
+ dlfield="`echo $chrome_downloaded | cut -d. -f$dotfield`"
+ ltfield="`echo $chrome_latest | cut -d. -f$dotfield`"
+ if [ "$dlfield" != "" -a "$ltfield" != "" ]
+ then
+ if [ $dlfield -lt $ltfield ]
+ then
+ error "Downloaded Google Chrome RPM version ($chrome_downloaded) is older than the latest one ($chrome_latest)"
+ else
+ # If the downloaded version field is definitely higher, then
+ # it's the new latest version and we exit the loop early
+ if [ $dlfield -gt $ltfield ]
+ then
+ chrome_latest="$chrome_downloaded"
+ dotfield=4
+ fi
+ fi
+ fi
+ let dotfield=$dotfield+1
+ done
+ fi
+
+ message "$chrome_name downloaded successfully" "n"
+}
+
+install_chrome_rpm()
+# We force install the RPM because RHEL/CentOS 6's packages
+# are below the minimum requirements now
+{
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would force-install $chrome_rpm RPM and"
+ echo "then check the installed version number is the one it should be"
+ return
+ fi
+
+ message "Installing $chrome_name RPM (please wait)"
+
+ check_binary_not_running
+ rm -f "$inst_tree/chrome"
+
+ # Remove soft-link for bug fix if it exists
+ if [ -h $chrome_desktop ]
+ then
+ rm -f $chrome_desktop
+ fi
+
+ # Fix beta/unstable RPM packaging bug by creating a soft-link to the
+ # .desktop file about to be unpacked, assuming that the stable package
+ # hasn't put one there already
+ if [ "$rpm_type" != "stable" -a ! -s $chrome_desktop ]
+ then
+ ln -sf $this_desktop $chrome_desktop
+ fi
+
+ rpm $rpm_options "$chrome_rpm"
+
+ if [ ! -x "$inst_tree/chrome" ]
+ then
+ error "Failed to install $chrome_name"
+ else
+ get_installed_version
+ if [ "$chrome_installed" = "$chrome_latest" ]
+ then
+ message "$chrome_name was installed successfully"
+ install_message="installed successfully"
+ final_warning
+ else
+ error "Newly-installed Google Chrome version ($chrome_installed) not the latest one ($chrome_latest)"
+ fi
+ fi
+}
+
+update_google_chrome()
+# Download and install the latest Google Chrome RPM
+# if it's either out of date or not installed yet
+{
+ get_installed_version
+ find_latest_chrome_version
+ get_downloaded_version
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would check if installed Google Chrome is the latest version."
+ echo "If it isn't, the latest version would be downloaded and installed."
+ echo
+ return
+ fi
+
+ if [ "$chrome_installed" = "$chrome_latest" -a "$chrome_latest" != "" ]
+ then
+ message "$chrome_name is already installed - skipping installation"
+ else
+ if [ "$chrome_downloaded" != "$chrome_latest" -o "$chrome_latest" = "" ]
+ then
+ download_chrome_rpm
+ fi
+ install_chrome_rpm
+ fi
+}
+
+init_setup()
+# Get everything setup and do a few basic checks
+{
+ if [ $quiet -lt 2 ]
+ then
+ echo "$chrome_name $inst_str $version on the $arch platform"
+ echo "(C) Richard K. Lloyd `date +%Y` "
+ show_space_used
+ echo
+ fi
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Running in dry-run mode (-n) - none of the actions below will be performed."
+ if [ $quiet -ne 0 ]
+ then
+ echo "Please note that combining dry-run and quiet modes isn't a good idea,"
+ echo "but I'll continue anyway just to keep you happy."
+ fi
+ echo
+ fi
+
+ # Must run this script as root
+ if [ `id -u` -ne 0 ]
+ then
+ error "You must run $scriptname as the superuser (usually root)"
+ fi
+
+ if [ "$tmp_tree" = "" -o "$tmp_tree" = "/tmp" -o "$tmp_tree" = "/" ]
+ then
+ error "Temporary directory location ($tmp_tree) incorrect"
+ fi
+
+ if [ $do_install -eq 0 ]
+ then
+ return
+ fi
+
+ if [ $dry_run -eq 1 ]
+ then
+ if [ ! -d "$tmp_tree" ]
+ then
+ echo "Would create temporary $tmp_tree directory"
+ fi
+ echo "Would change working directory to $tmp_tree"
+ echo
+ else
+ if [ ! -d "$tmp_tree" ]
+ then
+ message "Creating temporary directory $tmp_tree" "n"
+ mkdir -p "$tmp_tree"
+ if [ ! -d "$tmp_tree" ]
+ then
+ error "Couldn't create $tmp_tree directory"
+ fi
+ fi
+
+ message "Changing working directory to $tmp_tree" "n"
+ cd /
+ cd "$tmp_tree"
+ if [ "`pwd`" != "$tmp_tree" ]
+ then
+ error "Couldn't change working directory to $tmp_tree"
+ fi
+ fi
+}
+
+check_derivative()
+# Check for RHEL/CentOS 6 or 7 family
+{
+ case "`sed -e 's/ /_/g' /dev/null`" in
+ *_6.*) centos=6 ;;
+ *_7*) centos=7 ;;
+ *) echo
+ echo "This OS doesn't look like it's in the RHEL/CentOS 6 or 7 family."
+ echo "Very bad things could happen if you continue!"
+ echo
+ yesno "you want to continue" 2
+ if [ $ans -eq 1 ]
+ then
+ message "OK, but you've been warned (assuming RHEL/CentOS 7 family)"
+ centos=7
+ else
+ error "Probably a wise move"
+ fi ;;
+ esac
+
+ if [ $centos -eq 7 ]
+ then
+ # RHEL/CentOS 7 doesn't need chrome-deps-* RPM or build tools
+ deps_name="" ; deps_latest="latest"
+ fedlibs="was" ; scriptdeps=""
+ else
+ fedlibs="and extra libraries were"
+ scriptdeps=" and its dependencies added by this script"
+ fi
+}
+
+yum_install()
+# Download and Install specified packages if they aren't already installed
+# or they are installed, but out-of-date
+# $1 = "prompt" Prompt if any of $2.. aren't already installed
+# $2.. = List of packages to install
+{
+ # Nothing to install yet
+ install_list=""
+
+ if [ "$1" = "prompt" ]
+ then
+ prompt=1 ; promptstr="ask for"
+ else
+ prompt=0 ; promptstr="proceed with" ; ans=1
+ fi
+ shift
+
+ for each_dep in $*
+ do
+ if [ "`is_installed $each_dep`" = "" -o "`grep \"^$each_dep$\" $tmp_updates`" != "" ]
+ then
+ install_list="$install_list $each_dep"
+ fi
+ done
+
+ if [ "$install_list" != "" ]
+ then
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would $promptstr the installation of these packages and their dependencies:"
+ echo "$install_list"
+ echo
+ return
+ fi
+
+ echo
+ echo "The following packages and their dependencies need downloading/installing:"
+ echo
+ echo "$install_list"
+ if [ $prompt -eq 1 ]
+ then
+ echo
+ yesno "download/install these packages and dependencies"
+ fi
+
+ if [ $ans -eq 1 ]
+ then
+ message "Downloading/installing $install_list (please wait)"
+ yum $yum_options install $install_list
+ else
+ error "Those packages are required by this script"
+ fi
+ fi
+}
+
+request_reboot()
+# Request that the user reboots the machine after any upgrade
+# $1 = Kernel string number
+{
+ echo "You are STRONGLY RECOMMENDED to reboot this machine to run the new $1 kernel."
+ echo "If you don't, it's extremely likely $chrome_name will not run correctly."
+ echo "Please close all applications now (except this script!) if you want to reboot."
+ warning "These users are logged into this machine: `users | tr ' ' '\n' | sort -u`"
+
+ yesno "reboot this machine immediately" 3
+
+ if [ $ans -eq 1 ]
+ then
+ message "Rebooting machine now"
+ /sbin/shutdown -r now
+ exit 0
+ fi
+
+ error "You can't run $chrome_name until after the next reboot"
+}
+
+check_if_os_obsolete()
+# If OS version is less than 6.6, offer to upgrade (and abort if declined).
+# We need at least 6.6 because bad things happen in earlier versions
+{
+ os_version="`lsb_release -rs`"
+ case "$os_version" in
+ 6.0|6.1|6.2|6.3|6.4|6.5)
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would offer to upgrade your out-of-date OS (version $os_version)."
+ echo "If declined, the script will exit and warn you that you must"
+ echo "upgrade your OS (and preferably reboot) before it can continue."
+ echo
+ return
+ fi
+
+ echo "Your OS version ($os_version) is out-of-date and will therefore"
+ echo "not run $chrome_name correctly."
+ echo
+ yesno "upgrade your OS" 2
+
+ if [ $ans -eq 1 ]
+ then
+ message "Upgrading OS to latest release" "n"
+ message "You will have a final y/n prompt before updates are downloaded/installed"
+ yum update
+ new_os_version="`lsb_release -rs`"
+ if [ "$new_os_version" = "$os_version" ]
+ then
+ ans=0
+ else
+ message "Upgrade to OS version $new_os_version completed successfully"
+ request_reboot "$new_os_version"
+ fi
+ fi
+
+ if [ $ans -eq 0 ]
+ then
+ error "You declined an OS update to the latest release"
+ fi ;;
+ esac
+}
+
+check_if_kernel_obsolete()
+# Although a "yum update" may have been performed, users can exclude kernel updates
+# via the appropriate repo file (e.g. they may want to lock down the kernel to
+# a particular version that supports third-party binary drivers). The problem with this
+# is that recent Google Chrome releases immediately crash on RHEL/CentOS 6 with any
+# kernel shipped with RHEL CentOS 6.4 or earlier (i.e. 2.6.32-358.23.2.el6.x86_64 or
+# older). Such kernels need to be warned about that an update is needed.
+{
+ # Get the running kernel version as 4 dotted fields (4th is build nnumber)
+ kernelver="`uname -r | sed -e 's/-/./g' | cut -d. -f-4`"
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "If the running kernel ($kernelver) is too old, would offer to upgrade it"
+ echo "(and preferably reboot)."
+ echo
+ return
+ fi
+
+ dots=1 ; kernelok=1
+ for eachdot in 2 6 32 358
+ do
+ if [ $kernelok -eq 1 ]
+ then
+ kfield="`echo $kernelver | cut -d. -f$dots`"
+ case "$kfield" in
+ [0-9]*) # Is the kernel field a number?
+ if [ $kfield -gt $eachdot ]
+ then
+ # Running kernel is new enough, so return and do nothing
+ return
+ else
+ if [ $kfield -lt $eachdot ]
+ then
+ kernelok=0
+ else
+ let dots=$dots+1
+ fi
+ fi ;;
+ *) # Kernel field not a number, so custom version - let it through with a warning
+ warning "Running kernel version ($kernelver) contains a non-number - assuming a recent custom kernel"
+ return ;;
+ esac
+ fi
+ done
+
+ echo "Your running kernel version ($kernelver) is out-of-date and this will cause"
+ echo "$chrome_name to immediately crash."
+ echo
+ yesno "download/install the latest kernel" 2
+
+ if [ $ans -eq 1 ]
+ then
+ message "Upgrading kernel to latest release" "n"
+ message "You will have a final y/n prompt before the kernel updates are downloaded/installed"
+
+ kernelpacks=""
+ for eachpack in kernel kernel-devel kernel-firmware kernel-headers
+ do
+ if [ "`is_installed $eachpack`" != "" ]
+ then
+ kernelpacks="$kernelpacks $eachpack"
+ fi
+ done
+ yum update $kernelpacks
+
+ # Might have multiple kernel packages installed, so pick the numerically greatest one
+ # installed as the one that will run on the next reboot (if upgrade failed or was declined,
+ # this will probably mean the currently running old one ($kernelver)).
+ newkernelver="`rpm -q --queryformat '%{VERSION}.%{RELEASE}' kernel |
+ sed -e 's/-/./g' | cut -d. -f-4 |
+ sort -t. -n -r -k1,1 -k2,2 -k3,3 -k4,4 | head -1`"
+
+ if [ "$newkernelver" = "$kernelver" ]
+ then
+ error "You declined a kernel update to the latest release (or it failed)"
+ else
+ message "Download/install of latest kernel ($newkernelver) completed successfully"
+ request_reboot "$newkernelver"
+ fi
+ fi
+
+ if [ $ans -eq 0 ]
+ then
+ error "$chrome_name should not be run until you upgrade this machine's kernel via \"yum update\" and reboot it after the upgrade"
+ fi
+}
+
+install_prebuilt_library()
+# Download pre-built 64-bit libstdc++ library from script site
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would download and install the $download_lib library"
+ echo
+ return
+ fi
+
+ # We need to create library dir because we haven't installed
+ # the Google Chrome RPM yet
+ if [ ! -d "$libdir" ]
+ then
+ mkdir -p -m 755 "$libdir"
+ if [ ! -d "$libdir" ]
+ then
+ error "Can't create $chrome_name library dir ($libdir)"
+ fi
+ fi
+
+ download_file "$checksite$download_lib_xz" "$download_lib_xz" "3060059325 350920 $download_lib_xz" 1
+
+ destlib="$libdir/$download_lib"
+ xzcat -f "$download_lib_xz" >$destlib
+ if [ -s $destlib ]
+ then
+ chmod a+rx "$destlib"
+ change_se_context "$destlib"
+ message "Installed $destlib"
+ else
+ rm -f "$destlib"
+ error "Failed to install $download_lib"
+ fi
+}
+
+bulk_warning()
+# Multi-line warning message in $1, $2 and $3
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would display this warning to stderr:"
+ echo "$1"
+ echo "$2"
+ echo "$3"
+ else
+ echo >&2
+ echo "WARNING:" >&2
+ echo "$1" >&2
+ echo "$2" >&2
+ echo "$3." >&2
+ fi
+}
+
+final_messages()
+# Display final installation messages before exiting
+{
+ if [ $quiet -eq 2 -o $do_install -eq 0 ]
+ then
+ return
+ fi
+
+ echo
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would display these final messages after a successful run:"
+ echo
+ fi
+
+ echo "$chrome_name $fedlibs $install_message."
+ echo "Please run the browser via the '`basename $chrome_wrapper`' command as a non-root user."
+ final_warning
+ echo
+
+ echo "To update Google Chrome, run \"yum update $rpm_name\" or"
+ echo "simply re-run this script with \"./$scriptname\"."
+ echo
+ echo "To uninstall Google Chrome$scriptdeps,"
+ echo "run \"yum remove $rpm_name $deps_name\" or \"./$scriptname -u\"."
+ echo
+}
+
+parse_options()
+# Parse script options passed as $*
+{
+ delete_tmp=0 ; dry_run=0 ; re_run=0 ; do_install=1
+ inst_str="Installer"
+ risky_type="$old_rpm_type"
+
+ while [ "x$1" != "x" ]
+ do
+ case "$1" in
+ -\?|-h|--help) show_syntax ; exit 0 ;;
+ -b|--beta) risky_type="beta" ;;
+ -d|--delete) delete_tmp=1 ;;
+ -f|--force) let force=$force+1 ;;
+ -n|--dryrun) dry_run=1 ;;
+ -q|--quiet) if [ $quiet -lt 2 ]
+ then
+ let quiet=$quiet+1
+ fi ;;
+ -r|--re-run) re_run=1 ;;
+ -s|--stable) risky_type="stable" ;;
+ -t|--tmpdir) shift ; set_tmp_tree "$1" ;;
+ -u|--uninstall) do_install=0 ; inst_str="Uninstaller" ;;
+ -U|--unstable) risky_type="unstable" ;;
+ *) show_syntax >&2
+ error "Invalid option ($1)" ;;
+ esac
+ shift
+ done
+
+ if [ $quiet -ne 0 ]
+ then
+ wget_options="$wget_options -q"
+ yum_options="$yum_options -q"
+ rpm_options="$rpm_options --quiet"
+ rpmbuild_options="$rpmbuild_options --quiet"
+ else
+ rpm_options="$rpm_options -vh"
+ chcon_options="$chcon_options -v"
+ fi
+
+ if [ "$risky_type" != "$old_rpm_type" ]
+ then
+ set_rpm_type "$risky_type"
+ fi
+}
+
+create_spec_file()
+# Create chrome-deps-*.spec file for building the chrome-deps-* RPM.
+# Many thanks to to Marcus Sandberg for his (public domain) spec file at
+# https://github.com/adamel/chrome-deps which I have used as a basis for the
+# spec file that this script creates.
+{
+ ( cat <<@EOF
+# Much of this spec file was taken from Marcus Sandberg's fine (public domain)
+# effort at https://github.com/adamel/chrome-deps although it has been
+# modified compared to his version.
+
+Name: @DEPS_NAME@
+Version: @DEPS_VERSION@
+Release: 1
+Summary: Dependencies required for Google Chrome 28+ on RHEL/CentOS 6 derivatives
+License: GPLv3+, GPLv3+ with exceptions, GPLv2+ with exceptions, public domain
+Group: System Environment/Libraries
+Obsoletes: chrome-deps
+Provides: @LIBDIR@/link-to-@MISSINGLIB@@RPMDEP@
+URL: @CHECKSITE@
+Vendor: Richard K. Lloyd and the Fedora Project
+Packager: Richard K. Lloyd
+BuildRoot: @BUILDROOT@
+
+%description
+Includes an later libstdc++ Library, a shared library
+(@MISSINGLIB@) and a soft-link to load in the original
+@MISSINGLIB@ system library. Also modifies Google Chrome's
+@CHROME_WRAPPER@ wrapper script to allow
+Google Chrome 28 or later to run on RHEL/CentOS 6 derivatives.
+The URL for the script that downloaded and re-packaged the
+later libstdc++ library in this RPM is
+@CHECKSITE@@SCRIPTNAME@
+and it is in the public domain.
+
+# List of libraries to include in the RPM
+%files
+%defattr(-,root,root,-)
+@MODIFY_WRAPPER@
+@LIBDIR@/libstdc++.so.6
+@LIBDIR@/@MISSINGLIB@
+@LIBDIR@/link-to-@MISSINGLIB@
+
+# No prep or build rules because it's all been done by @SCRIPTNAME@
+
+# Install a copy of libraries into build root
+%install
+rm -rf %{buildroot}
+mkdir -p -m 755 %{buildroot}@LIBDIR@
+cp -pf @MODIFY_WRAPPER@ %{buildroot}@INST_TREE@
+cp -pf @LIBDIR@/lib*.so.* %{buildroot}@LIBDIR@/
+ln -sf /@RELUSRLIB@/@MISSINGLIB@ %{buildroot}@LIBDIR@/link-to-@MISSINGLIB@
+
+# Run modify_wrapper once the files are installed
+%post
+@MODIFY_WRAPPER@
+
+# At end of build, remove build root
+%clean
+rm -rf %{buildroot}
+
+# Changelog, with annoyingly "wrong" US date format
+%changelog
+* Thu May 4 2017 Richard K. Lloyd - 4.00-1
+- New libstdc++ library release.
+* Thu Dec 22 2016 Richard K. Lloyd - 3.15-1
+- New libstdc++ library release.
+* Fri Aug 26 2016 Richard K. Lloyd - 3.14-1
+- New libstdc++ library release.
+* Fri Apr 29 2016 Richard K. Lloyd - 3.13-1
+- New libstdc++ library release.
+* Tue Dec 15 2015 Richard K. Lloyd - 3.12-1
+- New libstdc++ library release.
+* Tue Feb 23 2015 Richard K. Lloyd - 3.11-1
+- Added a Provides: line to avoid an RPM dependency issue.
+* Fri Feb 6 2015 Richard K. Lloyd - 3.10-1
+- LD_PRELOAD unset_var.so library finally removed.
+- Created new single-function @MISSINGLIB@ library.
+- Added link-to-@MISSINGLIB@ soft-link to bring in
+ functions from system-installed @MISSINGLIB@.
+* Mon Feb 2 2015 Richard K. Lloyd - 3.00-1
+- Removed all patched Fedora libraries.
+- Added an unpatched libstdc++ library (from gcc or CentOS 7).
+* Fri Aug 29 2014 Richard K. Lloyd - 2.10-1
+- Added "Obsoletes: chrome-deps" to spec file.
+- Redirected stdout/stderr to /dev/null in google-chrome script.
+* Sun Jul 27 2014 Richard K. Lloyd - 2.00-1
+- Scan for all three RPM types in /etc/defaults/chrome.
+* Sat May 17 2014 Richard K. Lloyd - 1.21-1
+- Unset LD_LIBRARY_PATH for self-calls to the google-chrome script
+ Fedora @KEYRINGVER@ RPM.
+* Sat Apr 12 2014 Richard K. Lloyd - 1.20-1
+- Added libgnome-keyring.so.0, extracted from the libgnome-keyring
+ Fedora @KEYRINGVER@ RPM.
+* Wed Dec 11 2013 Richard K. Lloyd - 1.10-1
+- Additionally saved/unset/restored the LD_PRELOAD environmental
+ variable in unset_var.c to stop exec'ed() processes using it.
+* Sat Oct 5 2013 Richard K. Lloyd - 1.03-1
+- Added libgdk_pixbuf-2.0.so.0, extracted from the gdk-pixbuf2
+ Fedora @FEDVER@ RPM.
+* Fri Oct 4 2013 Richard K. Lloyd - 1.02-1
+- Added libgio-2.0 and libgobject-2.0 to the set of included
+ Fedora @FEDVER@ libraries.
+* Thu Aug 8 2013 Richard K. Lloyd - 1.01-1
+- Updated unset_var.c to fix Google Talk Plugin crash.
+* Sun Jul 28 2013 Richard K. Lloyd - 1.00-1
+- Initial version based on Marcus Sandberg's fine work at
+ https://github.com/adamel/chrome-deps (differences are below).
+- All the Fedora @FEDVER@ and @KEYRINGVER@ library downloads, unpacking and modifications are
+ done in the @SCRIPTNAME@ script that generated this spec file, rather
+ than run as spec file commands.
+- LD_PRELOAD unset_var.so library and @MODIFY_WRAPPER@
+ script are both included in the built RPM.
+@EOF
+ ) | sed \
+ -e "s#@DEPS_VERSION@#$deps_version#g" \
+ -e "s#@DEPS_NAME@#$deps_name#g" \
+ -e "s#@CHECKSITE@#$checksite#g" \
+ -e "s#@FEDVER@#$fedver#g" \
+ -e "s#@SCRIPTNAME@#$scriptname#g" \
+ -e "s#@LIBDIR@#$libdir#g" \
+ -e "s#@MISSINGLIB@#$missinglib#g" \
+ -e "s#@RPMDEP@#$rpmdep#g" \
+ -e "s#@RELUSRLIB@#$relusrlib#g" \
+ -e "s#@CHROME_WRAPPER@#$chrome_wrapper#g" \
+ -e "s#@MODIFY_WRAPPER@#$modify_wrapper#g" \
+ -e "s#@INST_TREE@#$inst_tree#g" \
+ -e "s#@BUILDROOT@#$rpmbuilddir/BUILDROOT#g" \
+ >"$specfile"
+}
+
+setup_build_env()
+# Create RPM build environment under %_topdir and also
+# create the chrome-deps-*.spec file
+{
+ rpmbuilddir="`rpm --eval %_topdir`"
+ if [ "$rpmbuilddir" = "" -o "$rpmbuilddir" = "%_topdir" ]
+ then
+ error "Can't determine RPM build dir"
+ fi
+ built_rpm="$rpmbuilddir/RPMS/$rpmarch/$built_rpm_base"
+ specsdir="$rpmbuilddir/SPECS"
+ specfile="$specsdir/$deps_name.spec"
+ setuptree="/usr/bin/rpmdev-setuptree"
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would create the build environment tree ($rpmbuilddir)"
+ echo "and also the $deps_name spec file ($specfile)."
+ echo
+ return
+ fi
+
+ if [ ! -d "$specsdir" ]
+ then
+ if [ -x "$setuptree" ]
+ then
+ $setuptree
+ fi
+
+ if [ ! -d "$specsdir" ]
+ then
+ error "Unable to correctly run $setuptree to create build environment"
+ fi
+ fi
+}
+
+build_deps_rpm()
+# Create chrome-deps-* RPM from the chrome-deps-*.spec file and install it
+{
+ built_rpm_base="$deps_name-$deps_version-1.$rpmarch.rpm"
+ tmpdir_rpm="$tmp_tree/$built_rpm_base"
+
+ # Only build latest chrome-deps-* RPM if we haven't already got it
+ if [ ! -s "$tmpdir_rpm" ]
+ then
+ # Get ready for RPM build
+ setup_build_env
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would run rpmbuild to create $tmpdir_rpm"
+ echo
+ else
+ # Create chrome-deps-*.spec file
+ create_spec_file
+
+ cd "$specsdir"
+ message "Building $tmpdir_rpm"
+ rm -f "$tmpdir_rpm"
+
+ rpmbuild $rpmbuild_options "`basename \"$specfile\"`"
+ rm -f "$specfile"
+
+ if [ -s "$built_rpm" ]
+ then
+ mv -f "$built_rpm" "$tmpdir_rpm"
+ built_rpm="$tmpdir_rpm"
+ fi
+
+ if [ ! -s "$built_rpm" ]
+ then
+ error "Failed to build $tmpdir_rpm"
+ fi
+ fi
+ fi
+
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would install $tmpdir_rpm"
+ echo
+ else
+ message "Installing $tmpdir_rpm"
+ rpm $rpm_options "$tmpdir_rpm"
+ fi
+}
+
+adjust_chrome_defaults()
+# Create a modify_wrapper script to be included in chrome-deps-* that modifies
+# /etc/default/google-chrome if necessary to doing the following
+# (for all 3 RPM tpyes):
+# - Remove any existing setting of repo_add_once
+# - Updates (or adds) a custom ### START .. ### END section, which will
+# ajusted the exec cat commands in google-chrome.
+# - Sets repo_add_once to true (picked up by /etc/cron.daily/google-chrome)
+# modify_wrapper is run once at the end of the chrome-deps-* RPM installation.
+{
+ if [ $dry_run -eq 1 ]
+ then
+ echo "Would create a modify_wrapper script to modify $chrome_defaults."
+ echo "The script would ensure the creation of $chrome_repo and"
+ echo "the adjustment of exec cat commands in $chrome_wrapper."
+ echo
+ return
+ fi
+
+ ( cat <<@EOF
+#! /bin/bash
+# @MODIFY_WRAPPER@ @WRAPPER_MOD_VERSION@ (C) Richard K. Lloyd 2017
+# Created by @SCRIPTNAME@ and included in the @DEPS_NAME@ RPM
+# to modify @CHROME_DEFAULTS@ in the following ways:
+# - Remove any existing setting of repo_add_once
+# - Updates (or adds) a custom ### START .. ### END section, which will
+# adjust the dubious "exec cat" commands in google-chrome.
+# - Sets repo_add_once to true (picked up by /etc/cron.daily/google-chrome)
+# @MODIFY_WRAPPER@ is run once at the end of the @DEPS_NAME@ RPM installation.
+
+chrome_defaults="@CHROME_DEFAULTS@"
+progname="\`basename \$0\`"
+
+error()
+{
+ echo "\$progname: ERROR: \$1 - aborted" >&2
+ exit 1
+}
+
+# Create defaults file if it doesn't exist
+touch "\$chrome_defaults"
+if [ ! -f "\$chrome_defaults" ]
+then
+ error "Can't create \$chrome_defaults"
+fi
+
+update_file()
+# \$1 = File to update with contents of stdin
+{
+ nfile="\$1.new" ; ofile="\$1.old"
+ cat >"\$nfile"
+ if [ ! -f "\$nfile" ]
+ then
+ rm -f "\$nfile"
+ error "Failed to create temporary update file \$nfile"
+ fi
+
+ # Don't do update if new file is the same as old one
+ if [ "\`diff \"\$1\" \"\$nfile\"\`" = "" ]
+ then
+ rm -f "\$nfile"
+ return
+ fi
+
+ mv -f "\$1" "\$ofile"
+ if [ ! -f "\$ofile" ]
+ then
+ error "Failed to create temporary backup of \$1"
+ fi
+
+ mv -f "\$nfile" "\$1"
+ rm -f "\$nfile"
+ if [ ! -f "\$1" ]
+ then
+ mv -f "\$ofile" "\$1"
+ chmod a+r "\$1"
+ error "Failed to update \$1"
+ fi
+
+ chmod a+r "\$1"
+ rm -f "\$ofile"
+}
+
+grep -v repo_add_once= "\$chrome_defaults" | awk '
+BEGIN { wrapper_mod=0; exclude_mod=0; end_of_mod=0; }
+{
+ if (\$4==scriptname)
+ {
+ if (\$2=="START")
+ {
+ if (\$3==wrapper_mod_version)
+ {
+ wrapper_mod=1; exclude_mod=0;
+ }
+ else exclude_mod=1;
+ }
+ else
+ if (\$2=="END") end_of_mod=1;
+ }
+
+ if (!exclude_mod) printf("%s\n",\$0);
+
+ if (end_of_mod) { exclude_mod=0; end_of_mod=0; }
+}
+END {
+ if (!wrapper_mod)
+ {
+ printf("### START %s %s modifications\n",
+ wrapper_mod_version,scriptname);
+ printf("old_line=\"exec cat\"\n");
+ printf("for eachtype in \"\" -beta -unstable\n");
+ printf("do\n");
+ printf(" chrome_wrapper=\"/opt/google/chrome\$eachtype/google-chrome\$eachtype\"\n");
+ printf(" if [ -s \"\$chrome_wrapper\" ]\n");
+ printf(" then\n");
+ printf(" if [ \"\`grep \\\\\"\$old_line\\\\\" \\\\\"\$chrome_wrapper\\\\\"\`\" != \"\" ]\n");
+ printf(" then\n");
+ printf(" new_wrapper=\"\$chrome_wrapper.new\"\n");
+ printf(" sed -e \"s#>(exec cat)#/dev/null#g\" -e \"s#>(exec cat >&2)#/dev/null#g\" <\"\$chrome_wrapper\" >\"\$new_wrapper\"\n");
+ printf(" if [ -s \"\$new_wrapper\" ]\n");
+ printf(" then\n");
+ printf(" mv -f \"\$new_wrapper\" \"\$chrome_wrapper\"\n");
+ printf(" chmod a+rx \"\$chrome_wrapper\"\n");
+ printf(" fi\n");
+ printf(" fi\n");
+ printf(" fi\n");
+ printf("done\n");
+ printf("### END %s %s modifications\n",
+ wrapper_mod_version,scriptname);
+ }
+ printf("repo_add_once=\"true\"\n");
+}' \
+wrapper_mod_version="@WRAPPER_MOD_VERSION@" scriptname="@SCRIPTNAME@" \
+customlib="@CUSTOMLIB@" |
+update_file "\$chrome_defaults"
+
+# Now actually run the defaults file (it will be run daily via cron or
+# when the google-chrome-stable RPM is installed or updated),
+# so that google-chrome is updated if it needs to be
+if [ -s "\$chrome_defaults" ]
+then
+ . "\$chrome_defaults"
+fi
+
+exit 0
+@EOF
+) | sed \
+ -e "s#@MODIFY_WRAPPER@#`basename \"$modify_wrapper\"`#g" \
+ -e "s#@WRAPPER_MOD_VERSION@#$wrapper_mod_version#g" \
+ -e "s#@SCRIPTNAME@#$scriptname#g" \
+ -e "s#@DEPS_NAME@#$deps_name#g" \
+ -e "s#@CHROME_DEFAULTS@#$chrome_defaults#g" \
+ -e "s#@DEPS_NAME@#$deps_name#g" \
+ -e "s#@CUSTOMLIB@#`basename \"$customlib\"`#g" \
+ >"$modify_wrapper"
+
+ if [ -s "$modify_wrapper" ]
+ then
+ chmod a+rx "$modify_wrapper"
+ change_se_context "$modify_wrapper"
+ message "Created $modify_wrapper successfully"
+ else
+ error "Failed to create $modify_wrapper"
+ fi
+}
+
+main_code()
+# Initialisation complete, so run the code
+{
+ # Get rid of old chrome-deps RPM
+ uninstall_rpms chrome-deps
+
+ if [ $do_install -eq 1 ]
+ then
+ # Only install RPM-building packages if latest chrome-deps-* isn't installed
+ # and we're using RHEL/CentOS 6.X
+ if [ "$deps_latest" = "" -a $centos -eq 6 ]
+ then
+ rpm_extra_packages="gcc glibc-devel rpm-build rpmdevtools"
+ else
+ rpm_extra_packages=""
+ fi
+
+ if [ $selinux_enabled -eq 1 ]
+ then
+ rpm_extra_packages="$rpm_extra_packages selinux-policy"
+ fi
+
+ # Make sure google-chrome-stable and chrome-deps-* dependencies are present
+ # but prompt for their download/install if any aren't
+ yum_install prompt redhat-lsb xdg-utils GConf2 libXScrnSaver libX11 gnome-keyring nss PackageKit libexif dbus $rpm_extra_packages
+
+ if [ $centos -eq 6 ]
+ then
+ # dbus will be installed by this point, but it must also be running
+ # and started up on the next reboot
+ if [ "`service messagebus status 2>/dev/null | grep running`" = "" ]
+ then
+ rm -f /var/run/messagebus.pid # Might have stayed after a crash
+ service messagebus start
+ chkconfig messagebus on
+ fi
+ fi
+
+ # Now update Google Chrome if necessary
+ update_google_chrome
+
+ if [ "$deps_latest" = "" -a $centos -eq 6 ]
+ then
+ # Download/install libstdc++ library
+ install_prebuilt_library
+
+ # Adjust /etc/default/google-chrome (sourced in daily by
+ # /etc/cron.daily/google-chrome) as required
+ adjust_chrome_defaults
+
+ # Build/install custom library if latest chrome-deps-* not installed
+ install_custom_lib
+
+ # Build and install the chrome-deps-* RPM if the latest isn't installed
+ build_deps_rpm
+
+ # That's the end of $libdir changes, so change its SELinux context type
+ change_se_context "$libdir"
+ fi
+ else
+ # If it's installed, uninstall Google Chrome and dependency packages
+ check_binary_not_running
+ uninstall_google_chrome
+ fi
+}
+
+check_selinux()
+# See if SELinux is enabled and if it's enforcing
+{
+ selinux_enforcing=0 ; selinux_enabled=0
+
+ # Yes, there's a value-returning util (0=enabled, ho hum, so we flip it)
+ # but it may not exist, so fallback on /selinux dir existence
+ if [ -x /usr/sbin/selinuxenabled ]
+ then
+ /usr/sbin/selinuxenabled
+ let selinux_enabled=1-$?
+ else
+ if [ -d /selinux ]
+ then
+ selinux_enabled=1
+ fi
+ fi
+
+ if [ $selinux_enabled -eq 1 ]
+ then
+ # Enforcing mode upsets nacl_helper, so try to see if we're using it
+ if [ -f /selinux/enforce ]
+ then
+ selinux_enforcing="`cat /selinux/enforce`"
+ fi
+ fi
+}
+
+init_packages()
+# Get a list of packages that are pending an update and
+# also make sure up-to-date wget and xz are installed early on
+# (for the version.dat download and possible script upgrade).
+{
+ message "Generating a list of out-of-date packages (please wait)"
+ yum list updates | egrep "($arch|noarch)" | awk '{ print $1 }' | cut -d. -f1 | sort -u >$tmp_updates
+ yum_install "" wget xz
+}
+
+# Initialisation functions
+init_vars $0
+check_derivative
+check_selinux
+parse_options $*
+check_binary_not_running
+init_setup
+init_packages
+check_version $*
+
+# Now do the install or uninstall
+main_code
+
+# Finalisation functions
+clean_up
+final_messages
+
+if [ $do_install -eq 1 ]
+then
+ # Need at least version 6.6 of OS to run Google Chrome successfully
+ check_if_os_obsolete
+
+ # Also need at least version 2.6.32.431 of the kernel
+ check_if_kernel_obsolete
+fi
+
+# A good exit
+exit 0