]> git.pld-linux.org Git - packages/mysql.git/blob - mysql.init
93986b298c34798379ff18082961f07d0ebe39f4
[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
336         # Install this in the user table, too
337         hostname="`hostname --fqdn 2> /dev/null | tr -d '[:space:]'`"
338         [ -z "$hostname" ] && hostname="localhost-unknown"
339
340         # Check if hostname is valid
341         if [ -z "$hostname" ]; then
342                 deltext
343                 fail
344                 nls "Sorry, the host name is not configured."
345                 nls "Please configure the 'hostname' command to return a hostname."
346                 exit 1
347         elif ! hostname -i >/dev/null 2>&1; then
348                 deltext
349                 fail
350                 nls "Sorry, the host '%s' could not be looked up." "$hostname"
351                 nls "Please configure the 'hostname' command to return a correct hostname."
352                 exit 1
353         fi
354
355         # Initialize variables
356         c_d="" i_d="" c_ht=""  c_tz=""
357         c_h="" i_h="" c_hc=""  c_tzt=""
358         c_u="" i_u="" c_hk=""  c_tztt=""
359         c_f="" i_f="" c_hr=""  c_tzls=""
360         c_t="" c_c="" c_tzn="" c_p=""
361         c_pp=""
362
363         # Check for old tables
364         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/db.frm
365         then
366           # mysqld --bootstrap wants one command/line
367           c_d="$c_d CREATE TABLE db ("
368           c_d="$c_d   Host char(60) DEFAULT '' NOT NULL,"
369           c_d="$c_d   Db char(64) DEFAULT '' NOT NULL,"
370           c_d="$c_d   User char(16) DEFAULT '' NOT NULL,"
371           c_d="$c_d   Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
372           c_d="$c_d   Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
373           c_d="$c_d   Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
374           c_d="$c_d   Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
375           c_d="$c_d   Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
376           c_d="$c_d   Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
377           c_d="$c_d   Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
378           c_d="$c_d   References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
379           c_d="$c_d   Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
380           c_d="$c_d   Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
381           c_d="$c_d   Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
382           c_d="$c_d   Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
383           c_d="$c_d   Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
384           c_d="$c_d   Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
385           c_d="$c_d   Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
386           c_d="$c_d   Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
387           c_d="$c_d   Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
388           c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
389           c_d="$c_d KEY User (User)"
390           c_d="$c_d )"
391           c_d="$c_d CHARACTER SET utf8 COLLATE utf8_bin"
392           c_d="$c_d comment='Database privileges';"
393
394           i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');
395           INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');"
396
397         fi
398
399         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/host.frm
400         then
401           c_h="$c_h CREATE TABLE host ("
402           c_h="$c_h  Host char(60) DEFAULT '' NOT NULL,"
403           c_h="$c_h  Db char(64) DEFAULT '' NOT NULL,"
404           c_h="$c_h  Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
405           c_h="$c_h  Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
406           c_h="$c_h  Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
407           c_h="$c_h  Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
408           c_h="$c_h  Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
409           c_h="$c_h  Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
410           c_h="$c_h  Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
411           c_h="$c_h  References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
412           c_h="$c_h  Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
413           c_h="$c_h  Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
414           c_h="$c_h  Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
415           c_h="$c_h  Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
416           c_h="$c_h  Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
417           c_h="$c_h  Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
418           c_h="$c_h  Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
419           c_h="$c_h  Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
420           c_h="$c_h  Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
421           c_h="$c_h  PRIMARY KEY Host (Host,Db)"
422           c_h="$c_h )"
423           c_h="$c_h CHARACTER SET utf8 COLLATE utf8_bin"
424           c_h="$c_h comment='Host privileges;  Merged with database privileges';"
425         fi
426
427         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/user.frm
428         then
429           c_u="$c_u CREATE TABLE user ("
430           c_u="$c_u   Host char(60) binary DEFAULT '' NOT NULL,"
431           c_u="$c_u   User char(16) binary DEFAULT '' NOT NULL,"
432           c_u="$c_u   Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL,"
433           c_u="$c_u   Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
434           c_u="$c_u   Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
435           c_u="$c_u   Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
436           c_u="$c_u   Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
437           c_u="$c_u   Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
438           c_u="$c_u   Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
439           c_u="$c_u   Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
440           c_u="$c_u   Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
441           c_u="$c_u   Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
442           c_u="$c_u   File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
443           c_u="$c_u   Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
444           c_u="$c_u   References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
445           c_u="$c_u   Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
446           c_u="$c_u   Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
447           c_u="$c_u   Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
448           c_u="$c_u   Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
449           c_u="$c_u   Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
450           c_u="$c_u   Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
451           c_u="$c_u   Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
452           c_u="$c_u   Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
453           c_u="$c_u   Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
454           c_u="$c_u   Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
455           c_u="$c_u   Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
456           c_u="$c_u   Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
457           c_u="$c_u   Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
458           c_u="$c_u   Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
459           c_u="$c_u   ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
460           c_u="$c_u   ssl_cipher BLOB NOT NULL,"
461           c_u="$c_u   x509_issuer BLOB NOT NULL,"
462           c_u="$c_u   x509_subject BLOB NOT NULL,"
463           c_u="$c_u   max_questions int(11) unsigned DEFAULT 0  NOT NULL,"
464           c_u="$c_u   max_updates int(11) unsigned DEFAULT 0  NOT NULL,"
465           c_u="$c_u   max_connections int(11) unsigned DEFAULT 0  NOT NULL,"
466           c_u="$c_u   max_user_connections int(11) unsigned DEFAULT 0  NOT NULL,"
467           c_u="$c_u   PRIMARY KEY Host (Host,User)"
468           c_u="$c_u ) engine=MyISAM"
469           c_u="$c_u CHARACTER SET utf8 COLLATE utf8_bin"
470           c_u="$c_u comment='Users and global privileges';"
471
472
473           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);
474           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);
475           INSERT INTO user (host,user) values ('localhost','');
476           INSERT INTO user (host,user) values ('$hostname','');
477           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);"
478         fi
479
480         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/func.frm
481         then
482           c_f="$c_f CREATE TABLE func ("
483           c_f="$c_f   name char(64) DEFAULT '' NOT NULL,"
484           c_f="$c_f   ret tinyint(1) DEFAULT '0' NOT NULL,"
485           c_f="$c_f   dl char(128) DEFAULT '' NOT NULL,"
486           c_f="$c_f   type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL,"
487           c_f="$c_f   PRIMARY KEY (name)"
488           c_f="$c_f )"
489           c_f="$c_f CHARACTER SET utf8 COLLATE utf8_bin"
490           c_f="$c_f comment='User defined functions';"
491         fi
492
493         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/tables_priv.frm
494         then
495           c_t="$c_t CREATE TABLE tables_priv ("
496           c_t="$c_t   Host char(60) DEFAULT '' NOT NULL,"
497           c_t="$c_t   Db char(64) DEFAULT '' NOT NULL,"
498           c_t="$c_t   User char(16) DEFAULT '' NOT NULL,"
499           c_t="$c_t   Table_name char(60) DEFAULT '' NOT NULL,"
500           c_t="$c_t   Grantor char(77) DEFAULT '' NOT NULL,"
501           c_t="$c_t   Timestamp timestamp(14),"
502           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,"
503           c_t="$c_t   Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
504           c_t="$c_t   PRIMARY KEY (Host,Db,User,Table_name),"
505           c_t="$c_t   KEY Grantor (Grantor)"
506           c_t="$c_t )"
507           c_t="$c_t CHARACTER SET utf8 COLLATE utf8_bin"
508           c_t="$c_t comment='Table privileges';"
509         fi
510
511         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/columns_priv.frm
512         then
513           c_c="$c_c CREATE TABLE columns_priv ("
514           c_c="$c_c   Host char(60) DEFAULT '' NOT NULL,"
515           c_c="$c_c   Db char(64) DEFAULT '' NOT NULL,"
516           c_c="$c_c   User char(16) DEFAULT '' NOT NULL,"
517           c_c="$c_c   Table_name char(64) DEFAULT '' NOT NULL,"
518           c_c="$c_c   Column_name char(64) DEFAULT '' NOT NULL,"
519           c_c="$c_c   Timestamp timestamp(14),"
520           c_c="$c_c   Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
521           c_c="$c_c   PRIMARY KEY (Host,Db,User,Table_name,Column_name)"
522           c_c="$c_c )"
523           c_c="$c_c CHARACTER SET utf8 COLLATE utf8_bin"
524           c_c="$c_c comment='Column privileges';"
525         fi
526
527         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/procs_priv.frm
528         then
529       c_pp="$c_pp CREATE TABLE procs_priv ("
530           c_pp="$c_pp   Host char(60) binary DEFAULT '' NOT NULL,"
531           c_pp="$c_pp   Db char(64) binary DEFAULT '' NOT NULL,"
532           c_pp="$c_pp   User char(16) binary DEFAULT '' NOT NULL,"
533           c_pp="$c_pp   Routine_name char(64) binary DEFAULT '' NOT NULL,"
534           c_pp="$c_pp   Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,"
535           c_pp="$c_pp   Grantor char(77) DEFAULT '' NOT NULL,"
536           c_pp="$c_pp   Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
537           c_pp="$c_pp   Timestamp timestamp(14),"
538           c_pp="$c_pp   PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),"
539           c_pp="$c_pp   KEY Grantor (Grantor)"
540           c_pp="$c_pp )"
541           c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin"
542           c_pp="$c_pp   comment='Procedure privileges';"
543     fi
544
545
546         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_topic.frm
547         then
548           c_ht="$c_ht CREATE TABLE help_topic ("
549           c_ht="$c_ht   help_topic_id    int unsigned not null,"
550           c_ht="$c_ht   name             varchar(64) not null,"
551       c_ht="$c_ht   help_category_id smallint unsigned not null,"
552           c_ht="$c_ht   description      text not null,"
553           c_ht="$c_ht   example          text not null,"
554           c_ht="$c_ht   url              varchar(128) not null,"
555           c_ht="$c_ht   primary key      (help_topic_id),"
556           c_ht="$c_ht   unique index     (name)"
557           c_ht="$c_ht )"
558           c_ht="$c_ht CHARACTER SET utf8"
559           c_ht="$c_ht comment='help topics';"
560         fi
561
562         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_category.frm
563         then
564           c_hc="$c_hc CREATE TABLE help_category ("
565           c_hc="$c_hc   help_category_id   smallint unsigned not null,"
566           c_hc="$c_hc   name               varchar(64) not null,"
567           c_hc="$c_hc   parent_category_id smallint unsigned null,"
568           c_hc="$c_hc   url                varchar(128) not null,"
569           c_hc="$c_hc   primary key        (help_category_id),"
570           c_hc="$c_hc   unique index       (name)"
571           c_hc="$c_hc )"
572           c_hc="$c_hc   CHARACTER SET utf8"
573           c_hc="$c_hc comment='help categories';"
574         fi
575
576         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_keyword.frm
577         then
578           c_hk="$c_hk CREATE TABLE help_keyword ("
579           c_hk="$c_hk   help_keyword_id  int unsigned not null,"
580           c_hk="$c_hk   name             varchar(64) not null,"
581           c_hk="$c_hk   primary key      (help_keyword_id),"
582           c_hk="$c_hk   unique index     (name)"
583           c_hk="$c_hk )"
584           c_hk="$c_hk   CHARACTER SET utf8"
585           c_hk="$c_hk comment='help keywords';"
586         fi
587
588         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/help_relation.frm
589         then
590           c_hr="$c_hr CREATE TABLE help_relation ("
591           c_hr="$c_hr   help_topic_id    int unsigned not null references help_topic,"
592           c_hr="$c_hr   help_keyword_id  int unsigned not null references help_keyword,"
593           c_hr="$c_hr   primary key      (help_keyword_id, help_topic_id)"
594           c_hr="$c_hr )"
595           c_hr="$c_hr   CHARACTER SET utf8"
596           c_hr="$c_hr comment='keyword-topic relation';"
597         fi
598
599         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_name.frm
600         then
601           c_tzn="$c_tzn CREATE TABLE time_zone_name ("
602           c_tzn="$c_tzn   Name char(64) NOT NULL,"
603           c_tzn="$c_tzn   Time_zone_id int unsigned NOT NULL,"
604           c_tzn="$c_tzn   PRIMARY KEY Name (Name)"
605           c_tzn="$c_tzn )"
606           c_tzn="$c_tzn   CHARACTER SET utf8"
607           c_tzn="$c_tzn comment='Time zone names';"
608         fi
609
610         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone.frm
611         then
612           c_tz="$c_tz CREATE TABLE time_zone ("
613           c_tz="$c_tz   Time_zone_id int unsigned NOT NULL auto_increment,"
614           c_tz="$c_tz   Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL,"
615           c_tz="$c_tz   PRIMARY KEY TzId (Time_zone_id)"
616           c_tz="$c_tz )"
617           c_tz="$c_tz   CHARACTER SET utf8"
618           c_tz="$c_tz comment='Time zones';"
619         fi
620
621         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_transition.frm
622         then
623           c_tzt="$c_tzt CREATE TABLE time_zone_transition ("
624           c_tzt="$c_tzt   Time_zone_id int unsigned NOT NULL,"
625           c_tzt="$c_tzt   Transition_time bigint signed NOT NULL,"
626           c_tzt="$c_tzt   Transition_type_id int unsigned NOT NULL,"
627           c_tzt="$c_tzt   PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)"
628           c_tzt="$c_tzt )"
629           c_tzt="$c_tzt   CHARACTER SET utf8"
630           c_tzt="$c_tzt comment='Time zone transitions';"
631         fi
632
633         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_transition_type.frm
634         then
635           c_tztt="$c_tztt CREATE TABLE time_zone_transition_type ("
636           c_tztt="$c_tztt   Time_zone_id int unsigned NOT NULL,"
637           c_tztt="$c_tztt   Transition_type_id int unsigned NOT NULL,"
638           c_tztt="$c_tztt   Offset int signed DEFAULT 0 NOT NULL,"
639           c_tztt="$c_tztt   Is_DST tinyint unsigned DEFAULT 0 NOT NULL,"
640           c_tztt="$c_tztt   Abbreviation char(8) DEFAULT '' NOT NULL,"
641           c_tztt="$c_tztt   PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)"
642           c_tztt="$c_tztt )"
643           c_tztt="$c_tztt   CHARACTER SET utf8"
644           c_tztt="$c_tztt comment='Time zone transition types';"
645         fi
646
647         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/time_zone_leap_second.frm
648         then
649           c_tzls="$c_tzls CREATE TABLE time_zone_leap_second ("
650           c_tzls="$c_tzls   Transition_time bigint signed NOT NULL,"
651           c_tzls="$c_tzls   Correction int signed NOT NULL,"
652           c_tzls="$c_tzls   PRIMARY KEY TranTime (Transition_time)"
653           c_tzls="$c_tzls )"
654           c_tzls="$c_tzls CHARACTER SET utf8"
655           c_tzls="$c_tzls   comment='Leap seconds information for time zones';"
656         fi
657
658         if test ! -f $MYSQL_DATA_DIR/mysqldb/mysql/proc.frm
659         then
660           c_p="$c_p CREATE TABLE proc ("
661           c_p="$c_p   db                char(64) collate utf8_bin DEFAULT '' NOT NULL,"
662           c_p="$c_p   name              char(64) DEFAULT '' NOT NULL,"
663           c_p="$c_p   type              enum('FUNCTION','PROCEDURE') NOT NULL,"
664           c_p="$c_p   specific_name     char(64) DEFAULT '' NOT NULL,"
665           c_p="$c_p   language          enum('SQL') DEFAULT 'SQL' NOT NULL,"
666           c_p="$c_p   sql_data_access   enum('CONTAINS_SQL',"
667           c_p="$c_p                          'NO_SQL',"
668           c_p="$c_p                          'READS_SQL_DATA',"
669           c_p="$c_p                          'MODIFIES_SQL_DATA'"
670           c_p="$c_p                     ) DEFAULT 'CONTAINS_SQL' NOT NULL,"
671           c_p="$c_p   is_deterministic  enum('YES','NO') DEFAULT 'NO' NOT NULL,"
672           c_p="$c_p   security_type     enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,"
673           c_p="$c_p   param_list        blob DEFAULT '' NOT NULL,"
674           c_p="$c_p   returns           char(64) DEFAULT '' NOT NULL,"
675           c_p="$c_p   body              longblob DEFAULT '' NOT NULL,"
676           c_p="$c_p   definer           char(77) collate utf8_bin DEFAULT '' NOT NULL,"
677           c_p="$c_p   created           timestamp,"
678           c_p="$c_p   modified          timestamp,"
679           c_p="$c_p   sql_mode          set("
680           c_p="$c_p                         'REAL_AS_FLOAT',"
681           c_p="$c_p                         'PIPES_AS_CONCAT',"
682           c_p="$c_p                         'ANSI_QUOTES',"
683           c_p="$c_p                         'IGNORE_SPACE',"
684           c_p="$c_p                         'NOT_USED',"
685           c_p="$c_p                         'ONLY_FULL_GROUP_BY',"
686           c_p="$c_p                         'NO_UNSIGNED_SUBTRACTION',"
687           c_p="$c_p                         'NO_DIR_IN_CREATE',"
688           c_p="$c_p                         'POSTGRESQL',"
689           c_p="$c_p                         'ORACLE',"
690           c_p="$c_p                         'MSSQL',"
691           c_p="$c_p                         'DB2',"
692           c_p="$c_p                         'MAXDB',"
693           c_p="$c_p                         'NO_KEY_OPTIONS',"
694           c_p="$c_p                         'NO_TABLE_OPTIONS',"
695           c_p="$c_p                         'NO_FIELD_OPTIONS',"
696           c_p="$c_p                         'MYSQL323',"
697           c_p="$c_p                         'MYSQL40',"
698           c_p="$c_p                         'ANSI',"
699           c_p="$c_p                         'NO_AUTO_VALUE_ON_ZERO',"
700           c_p="$c_p                         'NO_BACKSLASH_ESCAPES',"
701           c_p="$c_p                         'STRICT_TRANS_TABLES',"
702           c_p="$c_p                         'STRICT_ALL_TABLES',"
703           c_p="$c_p                         'NO_ZERO_IN_DATE',"
704           c_p="$c_p                         'NO_ZERO_DATE',"
705           c_p="$c_p                         'INVALID_DATES',"
706           c_p="$c_p                         'ERROR_FOR_DIVISION_BY_ZERO',"
707           c_p="$c_p                         'TRADITIONAL',"
708           c_p="$c_p                         'NO_AUTO_CREATE_USER',"
709           c_p="$c_p                         'HIGH_NOT_PRECEDENCE'"
710           c_p="$c_p                     ) DEFAULT '' NOT NULL,"
711           c_p="$c_p   comment           char(64) collate utf8_bin DEFAULT '' NOT NULL,"
712           c_p="$c_p   PRIMARY KEY (db,name,type)"
713           c_p="$c_p )"
714           c_p="$c_p character set utf8"
715           c_p="$c_p comment='Stored Procedures';"
716         fi
717
718         mkdir -p "$MYSQL_DATA_DIR" > /dev/null 2>&1
719         # Using mysql:mysql for MYSQL_CLUSTER_DIR is creating SECURITY hole, root:root is proper
720         chown root:root "$MYSQL_CLUSTER_DIR"
721     chown mysql:mysql "$MYSQL_CLUSTER_DIR/mysqldb" "$MYSQL_DATA_DIR" > /dev/null 2>&1
722         chmod 751 "$MYSQL_CLUSTER_DIR" "$MYSQL_CLUSTER_DIR/mysqldb"
723
724         if [ -f /usr/share/mysql/mysqld.conf -a ! -f "$MYSQL_CLUSTER_DIR/mysqld.conf" ]; then
725             sed -e "s#\(datadir.*\)=.*#\1= $MYSQL_DATA_DIR#g" \
726                 -e "s#\(pid-file.*\)=.*#\1= $MYSQL_PIDFILE#g" \
727                 -e "s#\(socket.*\)=.*#\1= $MYSQL_SOCKET#g" \
728                 /usr/share/mysql/mysqld.conf > "$MYSQL_CLUSTER_DIR/mysqld.conf"
729             chown root:root "$MYSQL_CLUSTER_DIR/mysqld.conf"
730             chmod 640 "$MYSQL_CLUSTER_DIR/mysqld.conf"
731         fi
732
733         if [ ! -e /var/lib/mysql/mysql.sock ] || [ -L /var/lib/mysql/mysql.sock ] && [ -z "$(readlink /var/lib/mysql/mysql.sock)" ]; then
734                 sock=${MYSQL_SOCKET#/var/lib/mysql/} # make it relative if possible
735             ln -s "$sock" /var/lib/mysql/mysql.sock
736         fi
737
738         if /usr/sbin/mysqld --bootstrap --skip-grant-tables \
739             --datadir=$MYSQL_DATA_DIR --user=$MYSQL_USER << END_OF_DATA
740 CREATE DATABASE mysql;
741 use mysql;
742 $c_d
743 $i_d
744
745 $c_h
746 $i_h
747
748 $c_u
749 $i_u
750
751 $c_f
752 $i_f
753
754 $c_t
755 $c_c
756
757 $c_ht
758 $c_hc
759 $c_hk
760 $c_hr
761
762 $c_tzn
763 $c_tz
764 $c_tzt
765 $c_tztt
766 $c_tzls
767
768 $c_p
769 $c_pp
770 END_OF_DATA
771         then
772             ok
773         cat << END_OF_MSG
774
775 PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL USERS!
776 This is done (after starting database; press enter when asked for password) with:
777
778 /usr/bin/mysqladmin -u mysql -S $MYSQL_SOCKET password 'password'
779 /usr/bin/mysqladmin -h $hostname -u mysql -S $MYSQL_SOCKET password 'password'
780 /usr/bin/mysqladmin -u mysql_logrotate -S $MYSQL_SOCKET password 'password'
781
782 NOTE: mysql_logrotate password should be placed to $MYSQL_CONFIG in
783 mysqladmin section. See the manual for more instructions.
784
785 If you want to use new help tables in MySQL 4.1.x then you'll need to import the help data:
786 /usr/bin/mysql -u mysql -p -S $MYSQL_SOCKET mysql < /usr/share/mysql/fill_help_tables.sql
787
788 END_OF_MSG
789       else
790             fail
791             cat << END_OF_MSG
792 Installation of grant tables FAILED!
793
794 Examine the logs in $MYSQL_DATA_DIR for more information.  You can
795 also try to start the mysqld demon with:
796
797 /usr/sbin/mysqld --skip-grant &
798
799 You can use the command line tool /usr/bin/mysql to connect to the mysql
800 database and look at the grant tables:
801
802 shell> /usr/bin/mysql -u mysql mysql
803 mysql> show tables
804
805 Try 'mysqld --help' if you have problems with paths. Setting on
806 logging in /etc/mysqld.conf gives you a log in /var/log/mysql/log that
807 may be helpful. The latest information about MySQL is available on the
808 web at http://www.mysql.com/.
809
810 Please check PLD Linux ftp site for newer versions of this package.
811
812 Please consult the MySQL manual section: 'Problems running
813 mysql_install_db', and the manual section that describes problems on
814 your OS.  Another information source is the MySQL email archive.
815 Please check all of the above before mailing us!  And if you do mail
816 us, you MUST use the /usr/bin/mysqlbug script!
817
818 END_OF_MSG
819
820         exit 1
821         fi
822 }
823
824 #
825 # End of useful functions.
826 #
827
828 start() {
829         if [ ! -f $MYSQL_ERRLOG ]; then
830                 touch $MYSQL_ERRLOG
831         fi
832         chown mysql:mysql $MYSQL_ERRLOG
833         chmod 640 $MYSQL_ERRLOG
834
835         for mysqldir in $DB_CLUSTERS; do
836                 mysqlstatus "$mysqldir" start
837                 if [ "$MYSQL_STATUS" = "running" ]; then
838                         msg_already_running "MySQL $mysqldir"
839                 else
840                         mysqlstart "$mysqldir"
841                 fi
842         done
843         mysqlsubsys
844 }
845
846 stop() {
847         for mysqldir in $DB_CLUSTERS; do
848                 mysqlstatus "$mysqldir" stop
849                 if [ "$MYSQL_STATUS" = "not running" ]; then
850                         msg_not_running "MySQL $mysqldir"
851                 else
852                         mysqlstop "$mysqldir"
853                 fi
854         done
855         mysqlsubsys
856 }
857
858 RETVAL=0
859 case "$action" in
860   start)
861         start
862         ;;
863   stop)
864         stop
865         ;;
866   status)
867         for mysqldir in $DB_CLUSTERS; do
868                 mysqlstatus "$mysqldir"
869                 if [ "$MYSQL_STATUS" = "running" ]; then
870                         show "MySQL cluster %s, PID %s" "$mysqldir" "$MYSQL_PID"
871                         progress "$MYSQL_STATUS"
872                 else
873                         show "MySQL cluster %s" "$mysqldir"
874                         progress "$MYSQL_STATUS" "$CFAIL"
875                 fi
876                 echo
877         done
878         exit $?
879         ;;
880   restart|force-reload)
881         stop
882         start
883         ;;
884   init)
885         for mysqldir in $DB_CLUSTERS; do
886                 mysqlinit "$mysqldir"
887         done
888         exit $?
889         ;;
890   flush-logs)
891         for mysqldir in $DB_CLUSTERS; do
892             mysqlgetconfig "$mysqldir"
893                 # just if mysqld is really running
894                 if /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" ping >/dev/null 2>&1; then
895                         /usr/bin/mysqladmin --defaults-file="$MYSQL_CONFIG" --socket="$MYSQL_SOCKET" flush-logs
896                 fi
897         done
898         ;;
899   *)
900         msg_usage "$0 {start|stop|init|restart|force-reload|status}"
901         exit 3
902 esac
903
904 exit $RETVAL
905
906 # vi: shiftwidth=4 tabstop=4
This page took 0.095988 seconds and 3 git commands to generate.