OSDN Git Service

Improved portsreintsall-chroot to allow unpriveliged enter, mount and unmount if...
[portsreinstall/current.git] / lib / main / libcommand.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # Overlay onto lib/libcommand.sh
5 # - Operations of commands as well as check of command line arguments -
6 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
7 # This software is distributed under the 2-Clause BSD License.
8 # ==============================================================================
9
10 # ============= Check the necessity of opening notice =============
11 command_all_chk_need_opening_notice ()
12 {
13         [ $COMMAND_MODE = do -o $COMMAND_MODE = redo -o $COMMAND_MODE = forget ]
14 }
15
16 # ============= Execute command operations before getting the temporary database ready =============
17 command_all_exec_before_db_creation ()
18 {
19         local COMMAND_RESTART COMMAND_MODE COMMAND_OPERATION
20         COMMAND_RESTART="$@"
21         COMMAND_MODE=${1:-do}
22         shift || :
23         case $COMMAND_MODE in
24         clean )
25                 COMMAND_OPERATION=${1:-normal}
26                 shift || :
27                 _command_parse_args__chk_no_arg $#
28                 case $COMMAND_OPERATION in
29                 force )
30                         message_echo "INFO: The temporary database is tried to be cleaned up without checking the privilege."
31                         database_maintain_clean_all
32                         message_echo "Done"
33                         exit
34                         ;;
35                 esac
36                 ;;
37         esac
38 }
39
40 # ============= Check and parse command line arguments =============
41 command_all_parse_args ()
42 {
43         local num_args_init
44         num_args_init=$#
45         COMMAND_RESTART="$@"
46         COMMAND_MODE=${1:-do}
47         shift || :
48         case $COMMAND_MODE in
49         clean )
50                 COMMAND_OPERATION=${1:-normal}
51                 shift || :
52                 case $COMMAND_OPERATION in
53                 normal )
54                         misc_chk_privilege
55                         ;;
56                 esac
57                 _command_parse_args__chk_no_arg $#
58                 ;;
59         reset )
60                 misc_chk_privilege
61                 COMMAND_OPERATION=${1:-all}
62                 shift || :
63                 case $COMMAND_OPERATION in
64                 all | keepopts | keepstatus )
65                         ;;
66                 *)
67                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be empty, \"all\" or \"keepopts\"." >&2
68                         exit 1
69                         ;;
70                 esac
71                 _command_parse_args__chk_no_arg $#
72                 ;;
73         ok | taboo | freeze | need | noneed )
74                 misc_chk_privilege
75                 [ $COMMAND_MODE = ok ] && database_query_chk_preparation_completion
76                 temp_warn_obsolete_temp_db >&2
77                 COMMAND_OPERATION=$1
78                 shift || :
79                 case $COMMAND_OPERATION in
80                 add | del )
81                         ;;
82                 '' )
83                         message_echo "ERROR: Missing operation which must be \"add\" or \"del\"." >&2
84                         exit 1
85                         ;;
86                 *)
87                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be \"add\" or \"del\"." >&2
88                         exit 1
89                         ;;
90                 esac
91                 _command_parse_args__chk_glob_args $#
92                 ;;
93         reselect )
94                 misc_chk_privilege
95                 database_query_chk_preparation_completion
96                 temp_warn_obsolete_temp_db >&2
97                 COMMAND_OPERATION=$1
98                 shift || :
99                 case $COMMAND_OPERATION in
100                 leaves )
101                         if [ -e "${DBDIR}/inspected_ports_only_partially" ]
102                         then
103                                 message_echo "ERROR: Leaf ports cannot be analyzed because the dependency inspection is partial." >&2
104                                 message_echo "Executing redo command with -N option by disabling -o option fixes this situation." >&2
105                                 exit 1
106                         fi
107                         ;;
108                 obsolete )
109                         ;;
110                 '' )
111                         message_echo "ERROR: Missing operation which must be \"leaves\" or \"obsolete\"." >&2
112                         exit 1
113                         ;;
114                 *)
115                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be \"leaves\" or \"obsolete\"." >&2
116                         exit 1
117                         ;;
118                 esac
119                 _command_parse_args__chk_glob_args $#
120                 ;;
121         save )
122                 misc_chk_privilege
123                 if [ ! -d "${DBDIR}" ]
124                 then
125                         message_echo "ERROR: The temporary database has not been created yet." >&2
126                         exit 1
127                 fi
128                 COMMAND_SAVE_DIR=$1
129                 shift || :
130                 _command_parse_args__chk_no_arg $#
131                 if [ -z "$COMMAND_SAVE_DIR" ]
132                 then
133                         message_echo "ERROR: Directory to save the temporary database archive is not specified." >&2
134                         exit 1
135                 fi
136                 if [ ! -d "$COMMAND_SAVE_DIR" ]
137                 then
138                         message_echo "ERROR: Directory [$COMMAND_SAVE_DIR] is not found." >&2
139                         exit 1
140                 fi
141                 ;;
142         load )
143                 misc_chk_privilege
144                 if database_maintain_chk_use
145                 then
146                         message_echo "ERROR: A temporary database exists." >&2
147                         message_echo "You must execute" >&2
148                         message_echo "        ${APPNAME} clean" >&2
149                         message_echo "before executing \"load\" command." >&2
150                         exit 1
151                 fi
152                 COMMAND_LOAD_FILE=$1
153                 shift || :
154                 _command_parse_args__chk_no_arg $#
155                 if [ -z "$COMMAND_LOAD_FILE" ]
156                 then
157                         message_echo "ERROR: No temporary database archive is specified." >&2
158                         exit 1
159                 fi
160                 if [ ! -f "$COMMAND_LOAD_FILE" ]
161                 then
162                         message_echo "ERROR: No such temporary database archive is found." >&2
163                         exit 1
164                 fi
165                 COMMAND_LOAD_FILE=`realpath "$COMMAND_LOAD_FILE"`
166                 ;;
167         glob | pkg )
168                 _command_parse_args__chk_glob_args $#
169                 ;;
170         options )
171                 _command_parse_args__chk_no_arg $#
172                 ;;
173         reconf | rmconf | forget | escape | restore | make )
174                 misc_chk_privilege
175                 temp_warn_obsolete_temp_db >&2
176                 _command_parse_args__chk_glob_args $#
177                 ;;
178         pkgsanity )
179                 misc_chk_privilege
180                 temp_warn_obsolete_temp_db >&2
181                 ;;
182         packupgrade )
183                 misc_chk_privilege
184                 COMMAND_OPERATION=$1
185                 shift || :
186                 case $COMMAND_OPERATION in
187                 create | clean )
188                         _command_parse_args__chk_no_arg $#
189                         ;;
190                 crop )
191                         COMMAND_PACKUPGRADE_SAVEPATH=${1:-${PROGRAM}-upgrade.tar.gz}
192                         shift || :
193                         _command_parse_args__chk_no_arg $#
194                         [ ! -d "${COMMAND_PACKUPGRADE_SAVEPATH}" ] ||  COMMAND_PACKUPGRADE_SAVEPATH=${COMMAND_PACKUPGRADE_SAVEPATH}/${PROGRAM}-upgrade.tar.gz
195                         ;;
196                 *)
197                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be \"create\" \"crop\" or \"clean\"." >&2
198                         exit 1
199                         ;;
200                 esac
201                 ;;
202         show )
203                 case $COMMAND_SHOW_SUBJECT in
204                 todo | done | redo | resolved | failure | deleted | restored | heritage | conflict | leaves | obsolete )
205                         database_query_chk_preparation_completion;;
206                 esac
207                 temp_warn_obsolete_temp_db >&2
208                 if ! expr "$1" : '@.*' > /dev/null
209                 then
210                         COMMAND_SHOW_SUBJECT=${1:-todo}
211                         shift || :
212                 else
213                         COMMAND_SHOW_SUBJECT=todo
214                 fi
215                 COMMAND_SHOW_OPTIONS=$1
216                 if expr "$COMMAND_SHOW_OPTIONS" : '@.*' > /dev/null
217                 then
218                         COMMAND_SHOW_DEPTAG=`expr "$COMMAND_SHOW_OPTIONS," : '@\(.*\)' | cut -d , -f 1` || :
219                         COMMAND_SHOW_LEVEL=`expr "$COMMAND_SHOW_OPTIONS," : '@\(.*\)' | cut -d , -f 2` || :
220                         case $COMMAND_SHOW_DEPTAG in
221                         all | run | build | '' )        ;;
222                         *)
223                                 message_echo "ERROR: Invalid show option [$COMMAND_SHOW_OPTIONS]." >&2
224                                 exit 1
225                                 ;;
226                         esac
227                         case $COMMAND_SHOW_LEVEL in
228                         full | direct | '' )    ;;
229                         *)
230                                 message_echo "ERROR: Invalid show option [$COMMAND_SHOW_OPTIONS]." >&2
231                                 exit 1
232                                 ;;
233                         esac
234                         shift || :
235                 fi
236                 case $COMMAND_SHOW_SUBJECT in
237                 todo | done | redo | resolved | inst_by_pkg | failure | taboo | freeze | need | noneed | restored | deleted | heritage | conflict )
238                         _command_parse_args__chk_no_arg $#
239                         ;;
240                 leaves | obsolete )
241                         COMMAND_SHOW_KEYWORD=$1
242                         case $COMMAND_SHOW_KEYWORD in
243                         '' | selected | unselected )    ;;
244                         *)
245                                 message_echo "ERROR: Invalid show $COMMAND_SHOW_SUBJECT keyword [$COMMAND_SHOW_KEYWORD]." >&2
246                                 exit 1
247                                 ;;
248                         esac
249                         shift || :
250                         _command_parse_args__chk_no_arg $#
251                         ;;
252                 build_conflict_pkgs | inst_conflict_pkgs | initrequirements | requirements | initdependents | dependents | conflict_files | status | errormessage )
253                         _command_parse_args__chk_glob_args $#
254                         ;;
255                 *)
256                         message_echo "ERROR: Invalid subject [$COMMAND_SHOW_SUBJECT]." >&2
257                         exit 1
258                         ;;
259                 esac
260                 ;;
261         all | prepare )
262                 COMMAND_DO_MODE=$COMMAND_MODE
263                 COMMAND_MODE=do
264                 misc_chk_privilege
265                 temp_warn_obsolete_temp_db >&2
266                 _command_parse_args__chk_no_arg $#
267                 ;;
268         redo | do )
269                 COMMAND_DO_MODE=${1:-all}
270                 shift || :
271                 case $COMMAND_DO_MODE in
272                 all | prepare );;
273                 *)
274                         message_echo "ERROR: Invalid operation mode [$COMMAND_DO_MODE]." >&2
275                         exit 1
276                         ;;
277                 esac
278                 misc_chk_privilege
279                 temp_warn_obsolete_temp_db >&2
280                 _command_parse_args__chk_no_arg $#
281                 if [ "$COMMAND_DO_MODE" = prepare ]
282                 then
283                         COMMAND_RESTART=prepare
284                 else
285                         COMMAND_RESTART=
286                 fi
287                 ;;
288         *)
289                 message_echo "ERROR: Invalid command [$COMMAND_MODE]." >&2
290                 exit 1
291                 ;;
292         esac
293         COMMAND_SHIFT=$(($num_args_init - $#))
294 }
295
296 # ============= Notify that option settings are reset =============
297 command_exec_without_pkgtools__notify_reset_options ()
298 {
299         message_echo "NOTE: Option settings are ignored (because of no effect) and reset."
300 }
301
302 # ============= Execute command operations which do not need package tools =============
303 command_all_exec_without_pkgtools ()
304 {
305         shift || :
306         case $COMMAND_MODE in
307         clean | load )
308                 command_exec_without_pkgtools__notify_reset_options
309                 case $COMMAND_MODE in
310                 clean )
311                         message_echo "Starting to clean up the temporary database..."
312                         database_maintain_clean_all
313                         ;;
314                 load )
315                         message_echo "Starting to load the temporary database from the archive..."
316                         database_maintain_load "$COMMAND_LOAD_FILE"
317                         ;;
318                 esac
319                 message_echo "Done"
320                 exit
321                 ;;
322         esac
323 }
324
325 # ============= Execute command operations which are irrespective of option settings =============
326 command_all_exec_irrespective_of_saved_options ()
327 {
328         local arcfile origins_match pkgs_match
329         shift || :
330         case $COMMAND_MODE in
331         ok )
332                 _command_exec_irrespective_of_saved_options__notify_ignored_options
333                 command_flexconf_update_ok "$@"
334                 exit
335                 ;;
336         taboo | freeze | need | noneed )
337                 _command_exec_irrespective_of_saved_options__notify_ignored_options
338                 mkdir -p "${DBDIR}/journal"
339                 echo "$@" >> ${DBDIR}/journal/$COMMAND_MODE
340                 case $COMMAND_MODE in
341                 taboo )
342                         command_flexconf_update_taboo "$@"
343                         ;;
344                 freeze )
345                         command_flexconf_update_freeze "$@"
346                         ;;
347                 need )
348                         program_deregister_stage_complete DETERMINE_SPECIFIED_TARGETS
349                         program_deregister_stage_complete ALL_COMPLETE
350                         command_flexconf_update_need "$@"
351                         ;;
352                 noneed )
353                         program_deregister_stage_complete INSPECT_PRIMARY_LEAF_PORTS
354                         program_deregister_stage_complete ALL_COMPLETE
355                         command_flexconf_update_noneed "$@"
356                         ;;
357                 esac
358                 exit
359                 ;;
360         reselect )
361                 case $COMMAND_OPERATION in
362                 leaves )
363                         if ! deinstall_select_leaf_ports_to_delete force
364                         then
365                                 case $? in
366                                 2 )
367                                         message_echo "INFO: No leaf port is found."
368                                         ;;
369                                 3 )
370                                         message_echo "INFO: Leaf ports are undefined because requirements of some ports are not fully inspected."
371                                         ;;
372                                 esac
373                         else
374                                 program_deregister_stage_complete COLLECT_LEAF_PORTS_TO_DELETE
375                                 program_deregister_stage_complete ALL_COMPLETE
376                         fi
377                         ;;
378                 obsolete )
379                         if ! deinstall_select_obsolete_ports_to_delete force
380                         then
381                                 case $? in
382                                 2 )
383                                         message_echo "INFO: No obsolete package is found."
384                                         ;;
385                                 esac
386                         else
387                                 program_deregister_stage_complete COLLECT_OBSOLETE_PORTS_TO_DELETE
388                                 program_deregister_stage_complete ALL_COMPLETE
389                         fi
390                         ;;
391                 esac
392                 exit
393                 ;;
394         save )
395                 _command_exec_irrespective_of_saved_options__notify_ignored_options
396                 arcfile=`realpath "$COMMAND_SAVE_DIR"`/${APPNAME}_`date +%Y%m%d_%H%M%S`.tar.gz
397                 message_echo "Starting to save the temporary database as [$arcfile]..."
398                 database_maintain_save "$arcfile"
399                 message_echo "Done"
400                 exit
401                 ;;
402         glob )
403                 _command_exec_irrespective_of_saved_options__notify_ignored_options
404                 origins_match=`pkgsys_eval_ports_glob "$@"`
405                 if  [ -n "$origins_match" ]
406                 then
407                         message_echo "Evaluated flavored port origins are as follows:"
408                         echo "$origins_match"
409                 else
410                         message_echo "No matching flavored port origin is found."
411                 fi
412                 exit
413                 ;;
414         pkg )
415                 _command_exec_irrespective_of_saved_options__notify_ignored_options
416                 message_echo "Evaluated installed package are as follows:"
417                 pkgs_match=`pkgsys_eval_ports_glob "$@" | while read origin
418                 do
419                         pkgsys_get_installed_pkg_from_origin "$origin"
420                 done`
421                 if  [ -n "$pkgs_match" ]
422                 then
423                         message_echo "Evaluated installed package are as follows:"
424                         echo "$pkgs_match"
425                 else
426                         message_echo "ERROR: No matching package is installed." >&2
427                         temp_terminate_process () { :; }
428                         exit 1
429                 fi
430                 exit
431                 ;;
432         reconf | rmconf | forget | escape | restore | pkgsanity | packupgrade )
433                 _command_exec_irrespective_of_saved_options__notify_ignored_options
434                 case $COMMAND_MODE in
435                 reconf | rmconf )
436                         command_pkgs_port_option_conf "$@"
437                         ;;
438                 forget )
439                         command_forget "$@"
440                         ;;
441                 escape )
442                         command_pkgs_escape "$@"
443                         ;;
444                 restore )
445                         command_pkgs_restore "$@"
446                         ;;
447                 pkgsanity )
448                         command_pkgs_pkgsanity "$@"
449                         ;;
450                 packupgrade )
451                         command_pkgs_packupgrade
452                         ;;
453                 esac
454                 message_echo "Done"
455                 exit
456                 ;;
457         redo )
458                 command_do_redo__command_all_exec_irrespective_of_saved_options
459                 ;;
460         esac
461 }
462
463 # ============= Execute command operations which should be done without upgrade of tools =============
464 command_all_exec_before_tools_upgrade ()
465 {
466         local glob origins errno
467         shift || :
468         case $COMMAND_MODE in
469         reset )
470                 message_echo "Starting to reset the temporary database by preserving the initial snapshot of installed packages..."
471                 if [ ! -d "${DBDIR}" ]
472                 then
473                         message_echo "INFO: No temporary database is built yet."
474                 else
475                         database_maintain_reset "$COMMAND_OPERATION"
476                         message_echo "INFO: Option settings and taboo/freeze/need/noneed lists are preserved."
477                 fi
478                 message_echo "Done"
479                 exit
480                 ;;
481         options )
482                 options_show_all
483                 exit
484                 ;;
485         show )
486                 command_show
487                 exit
488                 ;;
489         make )
490                 command_pkgs_make_ports "$@"
491                 exit
492                 ;;
493         esac
494 }
495
496 # ============= Execute command operations which must be done before the database construction =============
497 command_all_exec_before_build_database ()
498 {
499         case $COMMAND_MODE in
500         do )
501                 command_do_do__command_all_exec_before_build_database
502                 ;;
503         redo )
504                 command_do_redo__command_all_exec_before_build_database
505                 ;;
506         esac
507 }
508
509 # ============= Execute command operations of database construction =============
510 command_all_exec_build_database ()
511 {
512         case $COMMAND_MODE in
513         do | redo )
514                 command_do_prepare
515                 ;;
516         esac
517 }
518
519 # ============= Execute command operations which must be done before the main process =============
520 command_all_exec_before_main ()
521 {
522         case $COMMAND_MODE in
523         do | redo )
524                 case $COMMAND_DO_MODE in
525                 prepare )
526                         command_do_end_at_prepare_complete
527                         exit
528                         ;;
529                 esac
530                 ;;
531         esac
532 }
533
534 # ============= Execute command operations as the main process =============
535 command_all_exec_main ()
536 {
537         case $COMMAND_MODE in
538         do | redo )
539                 command_do_main
540                 command_do_ending_process
541                 ;;
542         esac
543 }