]> git.pld-linux.org Git - packages/mysql.git/blob - mysql.init
- use @clusterdir@ placeholder
[packages/mysql.git] / mysql.init
1 #!/bin/sh
2 #
3 # mysql         A very fast and reliable SQL database engine
4 #
5 # chkconfig:    2345 84 25
6 #
7 # description:  A very fast and reliable SQL database engine.
8 #
9 # Source function library
10 . /etc/rc.d/init.d/functions
11
12 # Get network config
13 . /etc/sysconfig/network
14
15 # Get service config
16 if [ -f /etc/sysconfig/mysql ]; then
17         . /etc/sysconfig/mysql
18 else
19         nls "Error: %s not found" /etc/sysconfig/mysql
20         nls "%s can't be run." MySQL
21         exit 1
22 fi
23
24 if [ -n "$MYSQL_DB_CLUSTERS" ]; then
25         nls "Warning: MYSQL_DB_CLUSTERS is set. It's obsolete. Use %s instead." /etc/mysql/clusters.conf
26 fi
27
28 if [ -f /etc/mysql/clusters.conf ]; then
29         MYSQL_DB_CLUSTERS=$(awk -F= '!/^#/{print $2}' /etc/mysql/clusters.conf)
30         if [ -z "$MYSQL_DB_CLUSTERS"  ]; then
31                 nls "Warning: there are no configured clusters."
32         fi
33
34 else
35         nls "Warning: Missing clusters config file %s" /etc/mysql/clusters.conf
36         if [ -z "$MYSQL_DB_CLUSTERS"  ]; then
37                 nls "Warning: there are no configured clusters."
38                 nls "Using default cluster /var/lib/mysql (compatibility mode)"
39                 MYSQL_DB_CLUSTERS=/var/lib/mysql
40         fi
41 fi
42
43
44 # Check that networking is up
45 if is_yes "${NETWORKING}"; then
46         if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status -a "$1" != init ]; then
47                 msg_network_down MySQL
48                 exit 1
49         fi
50 else
51         exit 0
52 fi
53
54 action="$1"
55
56 # any db cluster as command line argument?
57 if [ $# -gt 1 ]; then
58         shift
59         # perform action for specified clusters only
60         DB_CLUSTERS="$@"
61 else
62         DB_CLUSTERS="$MYSQL_DB_CLUSTERS"
63 fi
64
65 MYSQL_ERRLOG=/var/log/mysql/err
66 MYSQL_START_WAIT_TIME=${MYSQL_START_WAIT_TIME:-15}
67 MYSQL_STOP_WAIT_TIME=${MYSQL_STOP_WAIT_TIME:-900}
68
69 #
70 # Useful functions.
71 #
72
73 #
74 # check for mysql status
75 #
76 # arguments:
77 # $1 - db cluster
78 # $2 - start|stop
79 #
80 # sets variables:
81 # MYSQL_STATUS = starting | running | not running | died
82 # MYSQL_PID    = pid of mysqld process
83 #
84 mysqlstatus() {
85         clusterdir="$1"
86         mode="$2"
87         
88         mysqlgetconfig "$clusterdir"
89
90         MYSQL_STATUS="not running"
91         MYSQL_PID="unknown"
92         MYSQL_PIDFILE_PID=""
93         MYSQL_GREP_PID=""
94
95         if [ -f "$MYSQL_PIDFILE" ]; then
96                 MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
97         fi
98         
99         if [ -n "$MYSQL_PIDFILE_PID" ]; then
100                 MYSQL_PID=$MYSQL_PIDFILE_PID
101                 if [ ! -d "/proc/$MYSQL_PID" ]; then
102                         MYSQL_STATUS="died"
103                         return
104                 elif (grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null); then
105                         MYSQL_STATUS="running"
106                         return
107                 fi
108         fi
109
110         if [ "$mode" = "start" ]; then
111                 MYSQL_GREP_PID=$(grep -lE "^/usr/sbin/mysqld.*${MYSQL_PIDFILE}" /proc/[0-9]*/cmdline 2> /dev/null | awk -F "/" '{ print $3; exit; }')
112                 if [ -n "$MYSQL_GREP_PID" ]; then
113                         MYSQL_PID=$MYSQL_GREP_PID
114                         if grep -qa "$MYSQL_PIDFILE" /proc/$MYSQL_PID/cmdline 2> /dev/null; then
115                                 if [ -f "$MYSQL_PIDFILE" ]; then
116                                         MYSQL_PIDFILE_PID=$(cat "$MYSQL_PIDFILE")
117                                 fi
118                                 if [ -n "$MYSQL_PIDFILE_PID" ]; then
119                                         MYSQL_PID=$MYSQL_PIDFILE_PID
120                                         MYSQL_STATUS="running"
121                                         return
122                                 else
123                                         MYSQL_STATUS="starting"
124                                         return
125                                 fi
126                         fi
127                 fi
128         fi
129
130         # else default, "not running"
131 }
132
133 # get mysql configuration in variables
134 # MYSQL_CONFIG MYSQL_DATA_DIR MYSQL_USER MYSQL_PIDFILE
135 #
136 # arguments
137 # $1 - db cluster
138
139 mysqlgetconfig() {
140         clusterdir="$1"
141
142         # emulate old behaviour if only one cluster specified
143         if [ "$clusterdir" = "$MYSQL_DB_CLUSTERS" -a "$clusterdir" = "/var/lib/mysql" -a -f /etc/mysqld.conf ]; then
144                 MYSQL_RA_COMPAT=yes
145                 config_file=/etc/mysqld.conf
146         else
147                 config=$(awk -F= -vclusterdir="$clusterdir" '!/^#/{ if (clusterdir == $2) print $1}' /etc/mysql/clusters.conf)
148                 if [[ $config = /* ]]; then
149                         config_file="$config"
150                 elif [ -f "/etc/mysql/$config" ]; then
151                         config_file="/etc/mysql/$config"
152                 else
153                         config_file="$clusterdir/mysqld.conf"
154                 fi
155         fi
156
157         MYSQL_CLUSTER_DIR="$clusterdir"
158
159         if [ -z "$config_file" ]; then
160                 nls "Error: Can't find config file for %s cluster" "$clusterdir"
161                 exit 6
162         else
163                 MYSQL_CONFIG="$config_file"
164         fi
165
166         if [ ! -f "$config_file" ]; then
167                 nls "Error: config file %s not found" "$config_file"
168                 nls "MySQL can't be run. Did you initialize DB by doing \`$0 init'?"
169                 exit 6
170         fi
171
172         eval `awk '
173 /^[ \t]*\[.*\][ \t]*$/ {
174         match($0,/\[.*\]/)
175         section=substr($0, RSTART + 1, RSTART + RLENGTH - 3)
176 }
177 section == "mysqld" && $2 ~ "=" {
178         if ($1 == "datadir") {
179                 printf("MYSQL_DATA_DIR=%s;", $3)
180         } else if ($1 == "user") {
181                 printf("MYSQL_USER=%s;", $3)
182         } else if ($1 == "pid-file") {
183                 printf("MYSQL_PIDFILE=%s;", $3)
184         } else if ($1 == "socket") {
185                 printf("MYSQL_SOCKET=%s;", $3)
186         }
187 }
188 ' $config_file`
189
190
191         if is_yes "$MYSQL_RA_COMPAT"; then
192                 MYSQL_DATA_DIR_SUB=""
193         else
194                 MYSQL_DATA_DIR_SUB="/mysqldb"
195         fi
196
197         if [ -z "$MYSQL_DATA_DIR" -o "$MYSQL_DATA_DIR" != "${clusterdir}${MYSQL_DATA_DIR_SUB}/db" ]; then
198                 nls "Error: datadir specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/db"
199                 nls " MySQL can't be run."
200                 exit 6
201         fi
202
203         if [ -z "$MYSQL_PIDFILE" -o "$MYSQL_PIDFILE" != "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid" ]; then
204                 nls "Error: pid-file specified in %s should be %s" "$config_file" "$clusterdir${MYSQL_DATA_DIR_SUB}/mysql.pid"
205                 nls " MySQL can't be run."
206                 exit 6
207         fi
208
209         if [ -z $MYSQL_USER ]; then
210                 echo "$(nls 'MySQL user not configured properly')"'!' >&2
211                 nls "Edit %s and configure it." "$config_file" >&2
212                 exit 6
213         fi
214 }
215
216 # start mysql
217 mysqlstart() {
218         clusterdir="$1"
219         mysqlgetconfig "$clusterdir"
220         if [ ! -d "$MYSQL_DATA_DIR/mysql" ]; then
221                 nls "MySQL cluster %s not initialized." "$clusterdir"
222                 nls "Try \`%s init %s' before start." "$0" "$clusterdir"
223                 exit 6
224         fi
225
226         msg_starting "MySQL $clusterdir"
227         busy
228         [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
229         rm -f "$MYSQL_PIDFILE"
230         TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} /usr/bin/setsid /usr/sbin/mysqld --defaults-file=$MYSQL_CONFIG --datadir=$MYSQL_DATA_DIR --pid-file=$MYSQL_PIDFILE $MYSQL_OPTIONS >> $MYSQL_ERRLOG 2>&1 &
231         sleep 0.2
232         mysqlstatus "$clusterdir" start
233         # it takes longer for mysqld to start and create pidfile if it has to recover innodb transactions
234         if [ "$MYSQL_STATUS" = "starting" ]; then
235                 for nr in $(seq 1 $(($MYSQL_START_WAIT_TIME*10))); do
236                         [ -f "$MYSQL_PIDFILE" ] && break
237                         sleep 0.1
238                 done
239         fi
240
241         mysqlstatus "$clusterdir" start
242         if [ "$MYSQL_STATUS" = "running" -a "$MYSQL_PID" != "unknown" ]; then
243                 ok
244         elif [ "$MYSQL_STATUS" = "died" ]; then
245                 RETVAL=1
246                 died
247         else
248                 RETVAL=1
249                 fail
250         fi
251 }
252
253 # stop mysql
254 mysqlstop() {
255         clusterdir="$1"
256         mysqlstatus "$clusterdir" stop
257         msg_stopping "MySQL $clusterdir"
258         busy
259
260         # try graceful shutdown -- send shutdown command
261         # requires mysql_logrotate user proper privs
262         /usr/bin/mysqladmin --defaults-file=$MYSQL_CONFIG ${MYSQL_SOCKET:+--socket=$MYSQL_SOCKET} shutdown >/dev/null 2>&1
263         mysqlstatus "$clusterdir" stop
264
265         if [ "$MYSQL_PID" != "unknown" ]; then
266                 kill -TERM "$MYSQL_PID" 2> /dev/null
267                 for nr in $(seq 1 $(($MYSQL_STOP_WAIT_TIME*10))); do
268                         [ -d "/proc/$MYSQL_PID" ] || break
269                         sleep 0.1
270                 done
271         fi
272         
273         mysqlstatus "$clusterdir" stop
274         if [ "$MYSQL_STATUS" = "died" ]; then
275                 died
276         elif [ "$MYSQL_STATUS" = "running" -o "$MYSQL_STATUS" = "starting" ]; then
277                 fail
278         else
279                 ok
280         fi
281 }
282
283 #
284 # check for running mysql instances; if any instance is running then
285 # create subsys lock file
286 #
287 mysqlsubsys() {
288         # check for every defined db cluster in sysconfig file
289         for mysqldir in $DB_CLUSTERS; do
290                 mysqlstatus "$mysqldir"
291                 if [ "$MYSQL_STATUS" = "running" ]; then
292                         touch /var/lock/subsys/mysql
293                         return
294                 fi
295         done
296         rm -f /var/lock/subsys/mysql
297 }
298
299 mysqlinit() {
300         clusterdir="$1"
301
302         if [ -f /etc/mysqld.conf ]; then
303                 nls "Running in \`no cluster compat' mode: can't initialize database."
304                 nls "Move /etc/mysqld.conf away and rerun \`$0 init' (new config will be in $clusterdir)."
305                 exit 1
306         fi
307
308         if [ -f "$clusterdir/mysqld.conf" ]; then
309                 mysqlgetconfig "$clusterdir"
310         else
311                 MYSQL_USER="mysql"
312                 MYSQL_CLUSTER_DIR="$clusterdir"
313                 MYSQL_DATA_DIR="$clusterdir/mysqldb/db"
314                 MYSQL_PIDFILE="$clusterdir/mysqldb/mysql.pid"
315                 MYSQL_SOCKET="$clusterdir/mysqldb/mysql.sock"
316
317                 # this $MYSQL_CONFIG will be created later
318                 MYSQL_CONFIG="$MYSQL_CLUSTER_DIR/mysqld.conf"
319         fi
320
321         nls "Initializing cluster %s" "$clusterdir"
322
323         # Check if not exist init database
324         if [ -d "$MYSQL_DATA_DIR/mysql" ]; then
325                 nls "Seems that database is initialized now. Remove by hand %s" "$MYSQL_DATA_DIR/mysql"
326                 nls "before initializing database."
327                 nls "For now skipping cluster %s." "$clusterdir"
328                 return
329         fi
330
331         show "Creating privilege mysql tables for $MYSQL_DATA_DIR"
332         busy
333         TMP=/tmp TMPDIR=/tmp
334
335         # Install this in the user table, too
336         hostname="`hostname --fqdn 2> /dev/null | tr -d '[:space:]'`"
337         [ -z "$hostname" ] && hostname="localhost-unknown"
338
339         # Check if hostname is valid
340         if [ -z "$hostname" ]; then
341                 deltext
342                 fail
343                 nls "Sorry, the host name is not configured."
344                 nls "Please configure the 'hostname' command to return a hostname."
345                 exit 1
346         elif ! hostname -i >/dev/null 2>&1; then
347                 deltext
348                 fail
349                 nls "Sorry, the host '%s' could not be looked up." "$hostname"
350                 nls "Please configure the 'hostname' command to return a correct hostname."
351                 exit 1
352         fi
353
354         # Initialize variables
355         c_d="" i_d="" c_ht=""  c_tz=""
356         c_h="" i_h="" c_hc=""  c_tzt=""
357         c_u="" i_u="" c_hk=""  c_tztt=""
358         c_f="" i_f="" c_hr=""  c_tzls=""
359         c_t="" c_c="" c_tzn="" c_p=""
360         c_pp=""
361
362         # Check for old tables
363         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/db.frm
364         then
365           # mysqld --bootstrap wants one command/line
366           c_d="$c_d CREATE TABLE db ("
367           c_d="$c_d   Host char(60) DEFAULT '' NOT NULL,"
368           c_d="$c_d   Db char(64) DEFAULT '' NOT NULL,"
369           c_d="$c_d   User char(16) DEFAULT '' NOT NULL,"
370           c_d="$c_d   Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
371           c_d="$c_d   Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
372           c_d="$c_d   Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
373           c_d="$c_d   Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
374           c_d="$c_d   Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
375           c_d="$c_d   Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
376           c_d="$c_d   Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
377           c_d="$c_d   References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
378           c_d="$c_d   Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
379           c_d="$c_d   Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
380           c_d="$c_d   Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
381           c_d="$c_d   Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
382           c_d="$c_d   Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
383           c_d="$c_d   Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
384           c_d="$c_d   Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
385           c_d="$c_d   Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
386           c_d="$c_d   Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
387           c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
388           c_d="$c_d KEY User (User)"
389           c_d="$c_d )"
390           c_d="$c_d CHARACTER SET utf8 COLLATE utf8_bin"
391           c_d="$c_d comment='Database privileges';"
392
393           i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');
394           INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');"
395
396         fi
397
398         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/host.frm
399         then
400           c_h="$c_h CREATE TABLE host ("
401           c_h="$c_h  Host char(60) DEFAULT '' NOT NULL,"
402           c_h="$c_h  Db char(64) DEFAULT '' NOT NULL,"
403           c_h="$c_h  Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
404           c_h="$c_h  Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
405           c_h="$c_h  Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
406           c_h="$c_h  Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
407           c_h="$c_h  Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
408           c_h="$c_h  Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
409           c_h="$c_h  Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
410           c_h="$c_h  References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
411           c_h="$c_h  Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
412           c_h="$c_h  Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
413           c_h="$c_h  Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
414           c_h="$c_h  Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
415           c_h="$c_h  Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
416           c_h="$c_h  Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
417           c_h="$c_h  Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
418           c_h="$c_h  Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
419           c_h="$c_h  Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
420           c_h="$c_h  PRIMARY KEY Host (Host,Db)"
421           c_h="$c_h )"
422           c_h="$c_h CHARACTER SET utf8 COLLATE utf8_bin"
423           c_h="$c_h comment='Host privileges;  Merged with database privileges';"
424         fi
425
426         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/user.frm
427         then
428           c_u="$c_u CREATE TABLE user ("
429           c_u="$c_u   Host char(60) binary DEFAULT '' NOT NULL,"
430           c_u="$c_u   User char(16) binary DEFAULT '' NOT NULL,"
431           c_u="$c_u   Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL,"
432           c_u="$c_u   Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
433           c_u="$c_u   Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
434           c_u="$c_u   Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
435           c_u="$c_u   Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
436           c_u="$c_u   Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
437           c_u="$c_u   Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
438           c_u="$c_u   Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
439           c_u="$c_u   Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
440           c_u="$c_u   Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
441           c_u="$c_u   File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
442           c_u="$c_u   Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
443           c_u="$c_u   References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
444           c_u="$c_u   Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
445           c_u="$c_u   Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
446           c_u="$c_u   Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
447           c_u="$c_u   Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
448           c_u="$c_u   Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
449           c_u="$c_u   Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
450           c_u="$c_u   Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
451           c_u="$c_u   Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
452           c_u="$c_u   Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
453           c_u="$c_u   Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
454           c_u="$c_u   Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
455           c_u="$c_u   Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
456           c_u="$c_u   Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
457           c_u="$c_u   Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
458           c_u="$c_u   ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
459           c_u="$c_u   ssl_cipher BLOB NOT NULL,"
460           c_u="$c_u   x509_issuer BLOB NOT NULL,"
461           c_u="$c_u   x509_subject BLOB NOT NULL,"
462           c_u="$c_u   max_questions int(11) unsigned DEFAULT 0  NOT NULL,"
463           c_u="$c_u   max_updates int(11) unsigned DEFAULT 0  NOT NULL,"
464           c_u="$c_u   max_connections int(11) unsigned DEFAULT 0  NOT NULL,"
465           c_u="$c_u   max_user_connections int(11) unsigned DEFAULT 0  NOT NULL,"
466           c_u="$c_u   PRIMARY KEY Host (Host,User)"
467           c_u="$c_u ) engine=MyISAM"
468           c_u="$c_u CHARACTER SET utf8 COLLATE utf8_bin"
469           c_u="$c_u comment='Users and global privileges';"
470
471
472           i_u="INSERT INTO user VALUES ('localhost','mysql','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
473           INSERT INTO user VALUES ('$hostname',          'mysql','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
474           INSERT INTO user (host,user) values ('localhost','');
475           INSERT INTO user (host,user) values ('$hostname','');
476           INSERT INTO user VALUES ('localhost','mysql_logrotate','','N','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);"
477         fi
478
479         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/func.frm
480         then
481           c_f="$c_f CREATE TABLE func ("
482           c_f="$c_f   name char(64) DEFAULT '' NOT NULL,"
483           c_f="$c_f   ret tinyint(1) DEFAULT '0' NOT NULL,"
484           c_f="$c_f   dl char(128) DEFAULT '' NOT NULL,"
485           c_f="$c_f   type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL,"
486           c_f="$c_f   PRIMARY KEY (name)"
487           c_f="$c_f )"
488           c_f="$c_f CHARACTER SET utf8 COLLATE utf8_bin"
489           c_f="$c_f comment='User defined functions';"
490         fi
491
492         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/tables_priv.frm
493         then
494           c_t="$c_t CREATE TABLE tables_priv ("
495           c_t="$c_t   Host char(60) DEFAULT '' NOT NULL,"
496           c_t="$c_t   Db char(64) DEFAULT '' NOT NULL,"
497           c_t="$c_t   User char(16) DEFAULT '' NOT NULL,"
498           c_t="$c_t   Table_name char(60) DEFAULT '' NOT NULL,"
499           c_t="$c_t   Grantor char(77) DEFAULT '' NOT NULL,"
500           c_t="$c_t   Timestamp timestamp(14),"
501           c_t="$c_t   Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index', 'Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
502           c_t="$c_t   Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
503           c_t="$c_t   PRIMARY KEY (Host,Db,User,Table_name),"
504           c_t="$c_t   KEY Grantor (Grantor)"
505           c_t="$c_t )"
506           c_t="$c_t CHARACTER SET utf8 COLLATE utf8_bin"
507           c_t="$c_t comment='Table privileges';"
508         fi
509
510         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/columns_priv.frm
511         then
512           c_c="$c_c CREATE TABLE columns_priv ("
513           c_c="$c_c   Host char(60) DEFAULT '' NOT NULL,"
514           c_c="$c_c   Db char(64) DEFAULT '' NOT NULL,"
515           c_c="$c_c   User char(16) DEFAULT '' NOT NULL,"
516           c_c="$c_c   Table_name char(64) DEFAULT '' NOT NULL,"
517           c_c="$c_c   Column_name char(64) DEFAULT '' NOT NULL,"
518           c_c="$c_c   Timestamp timestamp(14),"
519           c_c="$c_c   Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
520           c_c="$c_c   PRIMARY KEY (Host,Db,User,Table_name,Column_name)"
521           c_c="$c_c )"
522           c_c="$c_c CHARACTER SET utf8 COLLATE utf8_bin"
523           c_c="$c_c comment='Column privileges';"
524         fi
525
526         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/procs_priv.frm
527         then
528       c_pp="$c_pp CREATE TABLE procs_priv ("
529           c_pp="$c_pp   Host char(60) binary DEFAULT '' NOT NULL,"
530           c_pp="$c_pp   Db char(64) binary DEFAULT '' NOT NULL,"
531           c_pp="$c_pp   User char(16) binary DEFAULT '' NOT NULL,"
532           c_pp="$c_pp   Routine_name char(64) binary DEFAULT '' NOT NULL,"
533           c_pp="$c_pp   Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,"
534           c_pp="$c_pp   Grantor char(77) DEFAULT '' NOT NULL,"
535           c_pp="$c_pp   Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
536           c_pp="$c_pp   Timestamp timestamp(14),"
537           c_pp="$c_pp   PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),"
538           c_pp="$c_pp   KEY Grantor (Grantor)"
539           c_pp="$c_pp )"
540           c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin"
541           c_pp="$c_pp   comment='Procedure privileges';"
542     fi
543
544
545         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_topic.frm
546         then
547           c_ht="$c_ht CREATE TABLE help_topic ("
548           c_ht="$c_ht   help_topic_id    int unsigned not null,"
549           c_ht="$c_ht   name             varchar(64) not null,"
550       c_ht="$c_ht   help_category_id smallint unsigned not null,"
551           c_ht="$c_ht   description      text not null,"
552           c_ht="$c_ht   example          text not null,"
553           c_ht="$c_ht   url              varchar(128) not null,"
554           c_ht="$c_ht   primary key      (help_topic_id),"
555           c_ht="$c_ht   unique index     (name)"
556           c_ht="$c_ht )"
557           c_ht="$c_ht CHARACTER SET utf8"
558           c_ht="$c_ht comment='help topics';"
559         fi
560
561         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_category.frm
562         then
563           c_hc="$c_hc CREATE TABLE help_category ("
564           c_hc="$c_hc   help_category_id   smallint unsigned not null,"
565           c_hc="$c_hc   name               varchar(64) not null,"
566           c_hc="$c_hc   parent_category_id smallint unsigned null,"
567           c_hc="$c_hc   url                varchar(128) not null,"
568           c_hc="$c_hc   primary key        (help_category_id),"
569           c_hc="$c_hc   unique index       (name)"
570           c_hc="$c_hc )"
571           c_hc="$c_hc   CHARACTER SET utf8"
572           c_hc="$c_hc comment='help categories';"
573         fi
574
575         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_keyword.frm
576         then
577           c_hk="$c_hk CREATE TABLE help_keyword ("
578           c_hk="$c_hk   help_keyword_id  int unsigned not null,"
579           c_hk="$c_hk   name             varchar(64) not null,"
580           c_hk="$c_hk   primary key      (help_keyword_id),"
581           c_hk="$c_hk   unique index     (name)"
582           c_hk="$c_hk )"
583           c_hk="$c_hk   CHARACTER SET utf8"
584           c_hk="$c_hk comment='help keywords';"
585         fi
586
587         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_relation.frm
588         then
589           c_hr="$c_hr CREATE TABLE help_relation ("
590           c_hr="$c_hr   help_topic_id    int unsigned not null references help_topic,"
591           c_hr="$c_hr   help_keyword_id  int unsigned not null references help_keyword,"
592           c_hr="$c_hr   primary key      (help_keyword_id, help_topic_id)"
593           c_hr="$c_hr )"
594           c_hr="$c_hr   CHARACTER SET utf8"
595           c_hr="$c_hr comment='keyword-topic relation';"
596         fi
597
598         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_name.frm
599         then
600           c_tzn="$c_tzn CREATE TABLE time_zone_name ("
601           c_tzn="$c_tzn   Name char(64) NOT NULL,"
602           c_tzn="$c_tzn   Time_zone_id int unsigned NOT NULL,"
603           c_tzn="$c_tzn   PRIMARY KEY Name (Name)"
604           c_tzn="$c_tzn )"
605           c_tzn="$c_tzn   CHARACTER SET utf8"
606           c_tzn="$c_tzn comment='Time zone names';"
607         fi
608
609         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone.frm
610         then
611           c_tz="$c_tz CREATE TABLE time_zone ("
612           c_tz="$c_tz   Time_zone_id int unsigned NOT NULL auto_increment,"
613           c_tz="$c_tz   Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL,"
614           c_tz="$c_tz   PRIMARY KEY TzId (Time_zone_id)"
615           c_tz="$c_tz )"
616           c_tz="$c_tz   CHARACTER SET utf8"
617           c_tz="$c_tz comment='Time zones';"
618         fi
619
620         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_transition.frm
621         then
622           c_tzt="$c_tzt CREATE TABLE time_zone_transition ("
623           c_tzt="$c_tzt   Time_zone_id int unsigned NOT NULL,"
624           c_tzt="$c_tzt   Transition_time bigint signed NOT NULL,"
625           c_tzt="$c_tzt   Transition_type_id int unsigned NOT NULL,"
626           c_tzt="$c_tzt   PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)"
627           c_tzt="$c_tzt )"
628           c_tzt="$c_tzt   CHARACTER SET utf8"
629           c_tzt="$c_tzt comment='Time zone transitions';"
630         fi
631
632         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_transition_type.frm
633         then
634           c_tztt="$c_tztt CREATE TABLE time_zone_transition_type ("
635           c_tztt="$c_tztt   Time_zone_id int unsigned NOT NULL,"
636           c_tztt="$c_tztt   Transition_type_id int unsigned NOT NULL,"
637           c_tztt="$c_tztt   Offset int signed DEFAULT 0 NOT NULL,"
638           c_tztt="$c_tztt   Is_DST tinyint unsigned DEFAULT 0 NOT NULL,"
639           c_tztt="$c_tztt   Abbreviation char(8) DEFAULT '' NOT NULL,"
640           c_tztt="$c_tztt   PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)"
641           c_tztt="$c_tztt )"
642           c_tztt="$c_tztt   CHARACTER SET utf8"
643           c_tztt="$c_tztt comment='Time zone transition types';"
644         fi
645
646         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_leap_second.frm
647         then
648           c_tzls="$c_tzls CREATE TABLE time_zone_leap_second ("
649           c_tzls="$c_tzls   Transition_time bigint signed NOT NULL,"
650           c_tzls="$c_tzls   Correction int signed NOT NULL,"
651           c_tzls="$c_tzls   PRIMARY KEY TranTime (Transition_time)"
652           c_tzls="$c_tzls )"
653           c_tzls="$c_tzls CHARACTER SET utf8"
654           c_tzls="$c_tzls   comment='Leap seconds information for time zones';"
655         fi
656
657         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/proc.frm
658         then
659           c_p="$c_p CREATE TABLE proc ("
660           c_p="$c_p   db                char(64) collate utf8_bin DEFAULT '' NOT NULL,"
661           c_p="$c_p   name              char(64) DEFAULT '' NOT NULL,"
662           c_p="$c_p   type              enum('FUNCTION','PROCEDURE') NOT NULL,"
663           c_p="$c_p   specific_name     char(64) DEFAULT '' NOT NULL,"
664           c_p="$c_p   language          enum('SQL') DEFAULT 'SQL' NOT NULL,"
665           c_p="$c_p   sql_data_access   enum('CONTAINS_SQL',"
666           c_p="$c_p                          'NO_SQL',"
667           c_p="$c_p                          'READS_SQL_DATA',"
668           c_p="$c_p                          'MODIFIES_SQL_DATA'"
669           c_p="$c_p                     ) DEFAULT 'CONTAINS_SQL' NOT NULL,"
670           c_p="$c_p   is_deterministic  enum('YES','NO') DEFAULT 'NO' NOT NULL,"
671           c_p="$c_p   security_type     enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,"
672           c_p="$c_p   param_list        blob DEFAULT '' NOT NULL,"
673           c_p="$c_p   returns           char(64) DEFAULT '' NOT NULL,"
674           c_p="$c_p   body              longblob DEFAULT '' NOT NULL,"
675           c_p="$c_p   definer           char(77) collate utf8_bin DEFAULT '' NOT NULL,"
676           c_p="$c_p   created           timestamp,"
677           c_p="$c_p   modified          timestamp,"
678           c_p="$c_p   sql_mode          set("
679           c_p="$c_p                         'REAL_AS_FLOAT',"
680           c_p="$c_p                         'PIPES_AS_CONCAT',"
681           c_p="$c_p                         'ANSI_QUOTES',"
682           c_p="$c_p                         'IGNORE_SPACE',"
683           c_p="$c_p                         'NOT_USED',"
684           c_p="$c_p                         'ONLY_FULL_GROUP_BY',"
685           c_p="$c_p                         'NO_UNSIGNED_SUBTRACTION',"
686           c_p="$c_p                         'NO_DIR_IN_CREATE',"
687           c_p="$c_p                         'POSTGRESQL',"
688           c_p="$c_p                         'ORACLE',"
689           c_p="$c_p                         'MSSQL',"
690           c_p="$c_p                         'DB2',"
691           c_p="$c_p                         'MAXDB',"
692           c_p="$c_p                         'NO_KEY_OPTIONS',"
693           c_p="$c_p                         'NO_TABLE_OPTIONS',"
694           c_p="$c_p                         'NO_FIELD_OPTIONS',"
695           c_p="$c_p                         'MYSQL323',"
696           c_p="$c_p                         'MYSQL40',"
697           c_p="$c_p                         'ANSI',"
698           c_p="$c_p                         'NO_AUTO_VALUE_ON_ZERO',"
699           c_p="$c_p                         'NO_BACKSLASH_ESCAPES',"
700           c_p="$c_p                         'STRICT_TRANS_TABLES',"
701           c_p="$c_p                         'STRICT_ALL_TABLES',"
702           c_p="$c_p                         'NO_ZERO_IN_DATE',"
703           c_p="$c_p                         'NO_ZERO_DATE',"
704           c_p="$c_p                         'INVALID_DATES',"
705           c_p="$c_p                         'ERROR_FOR_DIVISION_BY_ZERO',"
706           c_p="$c_p                         'TRADITIONAL',"
707           c_p="$c_p                         'NO_AUTO_CREATE_USER',"
708           c_p="$c_p                         'HIGH_NOT_PRECEDENCE'"
709           c_p="$c_p                     ) DEFAULT '' NOT NULL,"
710           c_p="$c_p   comment           char(64) collate utf8_bin DEFAULT '' NOT NULL,"
711           c_p="$c_p   PRIMARY KEY (db,name,type)"
712           c_p="$c_p )"
713           c_p="$c_p character set utf8"
714           c_p="$c_p comment='Stored Procedures';"
715         fi
716
717         mkdir -p "$MYSQL_DATA_DIR" > /dev/null 2>&1
718         # Using mysql:mysql for MYSQL_CLUSTER_DIR is creating SECURITY hole, root:root is proper
719         chown root:root "$MYSQL_CLUSTER_DIR"
720     chown mysql:mysql "$MYSQL_CLUSTER_DIR/mysqldb" "$MYSQL_DATA_DIR" > /dev/null 2>&1
721         chmod 751 "$MYSQL_CLUSTER_DIR" "$MYSQL_CLUSTER_DIR/mysqldb"
722
723         if [ -f /usr/share/mysql/mysqld.conf -a ! -f "$MYSQL_CLUSTER_DIR/mysqld.conf" ]; then
724             sed -e "
725                 s#\(datadir.*\)=.*#\1= $MYSQL_DATA_DIR#g;
726                 s#\(pid-file.*\)=.*#\1= $MYSQL_PIDFILE#g;
727                 s#\(socket.*\)=.*#\1= $MYSQL_SOCKET#g;
728                 s#@clusterdir@#$MYSQL_CLUSTER_DIR#g;
729                 " /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
730             chown root:root "$MYSQL_CLUSTER_DIR/mysqld.conf"
731             chmod 640 "$MYSQL_CLUSTER_DIR/mysqld.conf"
732         fi
733
734         if [ ! -e /var/lib/mysql/mysql.sock ] || [ -L /var/lib/mysql/mysql.sock ] && [ -z "$(readlink /var/lib/mysql/mysql.sock)" ]; then
735                 sock=${MYSQL_SOCKET#/var/lib/mysql/} # make it relative if possible
736             ln -s "$sock" /var/lib/mysql/mysql.sock
737         fi
738
739         if /usr/sbin/mysqld --bootstrap --skip-grant-tables \
740             --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER << END_OF_DATA
741 CREATE DATABASE mysql;
742 use mysql;
743 $c_d
744 $i_d
745
746 $c_h
747 $i_h
748
749 $c_u
750 $i_u
751
752 $c_f
753 $i_f
754
755 $c_t
756 $c_c
757
758 $c_ht
759 $c_hc
760 $c_hk
761 $c_hr
762
763 $c_tzn
764 $c_tz
765 $c_tzt
766 $c_tztt
767 $c_tzls
768
769 $c_p
770 $c_pp
771 END_OF_DATA
772         then
773             ok
774         cat << END_OF_MSG
775
776 PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
777 This is done (after starting database; press enter when asked for password) with:
778
779 /usr/bin/mysqladmin -u mysql -S $MYSQL_SOCKET password 'password'
780 /usr/bin/mysqladmin -h $hostname -u mysql -S $MYSQL_SOCKET password 'password'
781 /usr/bin/mysqladmin -u mysql_logrotate -S $MYSQL_SOCKET password 'password'
782
783 NOTE: mysql_logrotate password should be placed to $MYSQL_CONFIG in
784 mysqladmin section. See the manual for more instructions.
785
786 If you want to use new help tables in MySQL 4.1.x then you'll need to import the help data:
787 /usr/bin/mysql -u mysql -p -S $MYSQL_SOCKET mysql < /usr/share/mysql/fill_help_tables.sql
788
789 END_OF_MSG
790       else
791             fail
792             cat << END_OF_MSG
793 Installation of grant tables FAILED!
794
795 Examine the logs in $MYSQL_DATA_DIR for more information.  You can
796 also try to start the mysqld demon with:
797
798 /usr/sbin/mysqld --skip-grant &
799
800 You can use the command line tool /usr/bin/mysql to connect to the mysql
801 database and look at the grant tables:
802
803 shell> /usr/bin/mysql -u mysql mysql
804 mysql> show tables
805
806 Try 'mysqld --help' if you have problems with paths. Setting on
807 logging in /etc/mysqld.conf gives you a log in /var/log/mysql/log that
808 may be helpful. The latest information about MySQL is available on the
809 web at http://www.mysql.com/.
810
811 Please check PLD Linux ftp site for newer versions of this package.
812
813 Please consult the MySQL manual section: 'Problems running
814 mysql_install_db', and the manual section that describes problems on
815 your OS.  Another information source is the MySQL email archive.
816 Please check all of the above before mailing us!  And if you do mail
817 us, you MUST use the /usr/bin/mysqlbug script!
818
819 END_OF_MSG
820
821         exit 1
822         fi
823 }
824
825 #
826 # End of useful functions.
827 #
828
829 start() {
830         if [ ! -f $MYSQL_ERRLOG ]; then
831                 touch $MYSQL_ERRLOG
832         fi
833         chown mysql:mysql $MYSQL_ERRLOG
834         chmod 640 $MYSQL_ERRLOG
835
836         for mysqldir in $DB_CLUSTERS; do
837                 mysqlstatus "$mysqldir" start
838                 if [ "$MYSQL_STATUS" = "running" ]; then
839                         msg_already_running "MySQL $mysqldir"
840                 else
841                         mysqlstart "$mysqldir"
842                 fi
843         done
844         mysqlsubsys
845 }
846
847 stop() {
848         for mysqldir in $DB_CLUSTERS; do
849                 mysqlstatus "$mysqldir" stop
850                 if [ "$MYSQL_STATUS" = "not running" ]; then
851                         msg_not_running "MySQL $mysqldir"
852                 else
853                         mysqlstop "$mysqldir"
854                 fi
855         done
856         mysqlsubsys
857 }
858
859 RETVAL=0
860 case "$action" in
861   start)
862         start
863         ;;
864   stop)
865         stop
866         ;;
867   status)
868         for mysqldir in $DB_CLUSTERS; do
869                 mysqlstatus "$mysqldir"
870                 if [ "$MYSQL_STATUS" = "running" ]; then
871                         show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
872                         progress "$MYSQL_STATUS"
873                 else
874                         show "MySQL cluster %s" "$mysqldir"
875                         progress "$MYSQL_STATUS" "$CFAIL"
876                 fi
877                 echo
878         done
879         exit $?
880         ;;
881   restart|force-reload)
882         stop
883         start
884         ;;
885   init)
886         for mysqldir in $DB_CLUSTERS; do
887                 mysqlinit "$mysqldir"
888         done
889         exit $?
890         ;;
891   flush-logs)
892         for mysqldir in $DB_CLUSTERS; do
893             mysqlgetconfig "$mysqldir"
894                 # just if mysqld is really running
895                 if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
896                         /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
897                 fi
898         done
899         ;;
900   *)
901         msg_usage "$0 {start|stop|init|restart|force-reload|status}"
902         exit 3
903 esac
904
905 exit $RETVAL
906
907 # vi: shiftwidth=4 tabstop=4
This page took 0.105927 seconds and 4 git commands to generate.