darrenldl

ezsetfacl.sh

Jan 26th, 2014
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 122.83 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. # Author : darrenldl ([email protected])
  4.  
  5. # Initialisation
  6.  
  7. filelist=""
  8. users=()
  9. groups=()
  10.  
  11. line_no=1
  12. a_line_no=1
  13. file_no=0
  14. dir_no=0
  15. acl_block_no=0
  16. fl_start=0 # fl_start is used by second part of code
  17. fl_end=0 # fl_end is used by second part of code
  18. c_error=0 # c_error = config error
  19. c_warn=0 # c_warn = config warning counter ( non-critical mistakes )
  20. fl_o=0 # flag operation, is used to indicated finished operation
  21. fl_all=0 # fl_all is used to check if ALL is used
  22. fl_others=0 # fl_others is used to check if other words are used with ALL(if ALL is used, ALL should be the only operand)
  23. fl_u_valid_line=() # fl_u_valid stores flags to indicate whether users in config are present in users array, in the current line
  24. fl_u_checked=() # fl_u_checked stores if the user is already mentioned
  25. fl_g_valid_line=() # fl_g_valid stores flags to indicate whether groups in config are present in groups array, in the current line
  26. fl_g_checked=() # fl_g_checked stores if the group is already mentioned
  27. fl_u_check=0
  28. fl_g_check=0
  29. fl_u=() # fl_u is used by second part of code
  30. fl_g=() # fl_g ss used by second part of code
  31. fl_r_u=0
  32. fl_r_g=0
  33. fl_e_u=0
  34. fl_e_g=0
  35. fl_no=0 # fl_no is used in second part of code
  36. fl_no_b=0
  37. fl_f_list=0
  38. fl_e=0
  39. fl_i=1
  40. fl_l=0
  41. fl_f_list=0
  42. fl_f_list_type=0
  43. fl_perm_check=0
  44. fl_perm=0
  45. fl_dperm=0
  46. fl_recur=0
  47. fl_P=0
  48. fl_D=0
  49. fl_R=0
  50. fl_P_s=0
  51. fl_D_s=0
  52. fl_R_s=0
  53. fl_apply=0
  54. fl_gen=0
  55. fl_I_a=0
  56. fl_I_d=0
  57. fl_I_g=0
  58. fl_I_h=0
  59. fl_I_t=0
  60. fl_I_s=0
  61. fl_f_specified=0
  62. fl_NOALL=0
  63. temp=()
  64. temp2=0
  65. fl_debug=0
  66. fl_stray_c=0
  67. fl_stray_P_str=0
  68. fl_stray_D_str=0
  69. s_aperm=0
  70. fl_one_line_file=0
  71. fl_chown_c=0
  72. fl_chown_u=""
  73. fl_chown_g=""
  74. fl_chown_u_c=0
  75. fl_chown_g_c=0
  76. fl_chown_u_specified=0
  77. fl_chown_g_specified=0
  78. chmod_perm_string=""
  79. stray_no=0
  80. chown_no=0
  81. chown_file_no=0
  82. chown_dir_no=0
  83. chmod_no=0
  84. chmod_file_no=0
  85. chmod_dir_no=0
  86. fl_chattr_recur=0
  87. fl_chattr_verbose=0
  88. fl_chattr_version=0
  89. fl_chattr_version_c=0
  90. chattr_version_no=0
  91. chattr_no=0
  92. chattr_file_no=0
  93. chattr_string=""
  94. chattr_arg_string=""
  95. fl_start_type=0
  96. fl_w_list=0
  97. fl_w_list_type=0
  98. fl_append_specified=0
  99. fl_insert_specified=0
  100. fl_replace_specified=0
  101. append_no=0
  102. append_text_no=0
  103. append_file_no=0
  104. insert_no=0
  105. insert_text_no=0
  106. insert_file_no=0
  107. replace_no=0
  108. replace_old_text_no=0
  109. replace_new_text_no=0
  110. replace_file_no=0
  111.  
  112. append_string_buffer=""
  113. append_string_buffer_count=0
  114. fl_append_string_first=1
  115.  
  116. insert_string_buffer=""
  117. insert_string_buffer_count=0
  118. insert_string_buffer_after=""
  119. insert_string_buffer_after_count=0
  120. fl_insert_string_first=1
  121. fl_insert_string_after_first=1
  122. insert_string_buffer_array=()
  123. insert_string_buffer_after_array=()
  124. fl_insert_line=0
  125. fl_insert_after=0
  126. fl_insert_index=0
  127. fl_insert_index_after=0
  128. fl_insert_sed_mul_line_index=0
  129. insert_sed_mul_line_string_array=()
  130. fl_insert_block_completed=1
  131. insert_line_or_after=()
  132. insert_line_number=0
  133. insert_line_number_array=()
  134.  
  135. fl_replace_with=0
  136. fl_replace_index=0
  137. replace_string_buffer=""
  138. fl_replace_string_first=1
  139. replace_string_buffer_with=""
  140. fl_replace_string_with_first=1
  141. sed_mul_line_string=""
  142. replace_string_buffer_array=()
  143. replace_string_buffer_with_array=()
  144. fl_replace_block_completed=1
  145. replace_mul_line=0
  146.  
  147. fl_command_specified=0
  148. cmd_no=0
  149. cmd_line_no=0
  150.  
  151. fl_nm_list_ug=0
  152. fl_nm_list_ft=0
  153. fl_nm_list_specified=0
  154.  
  155. nm_list_file_no=0
  156. nm_list_file_line_no=0
  157. nm_list_file_a_line_no=0
  158. nm_list_user_no=0
  159. nm_list_group_no=0
  160. nm_list_no=0
  161.  
  162. nm_list_line_raw=""
  163. nm_list_word=""
  164. nm_list_line=()
  165.  
  166. nm_list_file=""
  167. fl_restrict_specified=0
  168.  
  169. file_name_stitch_c=0
  170. file_name_stitch_string=""
  171.  
  172. temp3=""
  173. temp4=""
  174. temp5=0
  175.  
  176. end_line_no=0
  177. end_temp_line_no=0
  178. end_line_array=()
  179. end_line_no_temp=0
  180. end_line_no_string=""
  181. end_line_raw=""
  182. end_word=""
  183. end_line=()
  184.  
  185. char_escape_warn_cw=0
  186. fl_I_cw_c=0
  187. char_escape_warn_w=1
  188. fl_I_w_c=0
  189.  
  190. filename_auto_stitch=0
  191. fl_I_fnas_c=0
  192. stray_file_index=0
  193. stray_file_array=()
  194.  
  195. after_line_no=0
  196. with_line_no=0
  197.  
  198. # Interface
  199. for (( i=1; i <= $#; i++ )); do
  200. temp=${!i}
  201. if [[ "$temp" == --* ]]; then
  202. case $temp in
  203. --apply )
  204. if (( $fl_I_a == 1 )); then
  205. echo " -a repeated"
  206. exit
  207. fi
  208. fl_I_a=1
  209. ;;
  210. --timestamp )
  211. if (( $fl_I_d == 1 )); then
  212. echo " -d repeated"
  213. exit
  214. fi
  215. fl_I_d=1
  216. ;;
  217. --generate )
  218. if (( $fl_I_g == 1 )); then
  219. echo " -g repeated"
  220. exit
  221. fi
  222. fl_I_g=1
  223. ;;
  224. --help )
  225. echo "Usage : ./ezsetfacl.sh [OPTIONS] [file list]"
  226. echo ""
  227. echo "Options :"
  228. echo " -a, --apply apply rules"
  229. echo " -d, --timestamp prepend a line for data and time"
  230. echo " -g, --generate generate commands"
  231. echo " -h, --help show help message"
  232. echo " -t, --test check errors only"
  233. echo " -s, --stat show statistics"
  234. echo ""
  235. echo " --cw, --commentedwarning show commented warning text messages in generate mode,"
  236. echo " regardless of whether apply mode is chosen"
  237. echo " --ncw, --nocommentedwarning do not show commented warning (default) "
  238. echo " --w --warning show warning text messages(default),"
  239. echo " only when only apply mode is chosen"
  240. echo " --nw, --nowarning do not show warning text messages,"
  241. echo " only when only apply mode is chosen"
  242. echo " --filename_auto_stitch adds '\' automatically to file names with spaces if not already"
  243. echo " Warning: auto_stitch will render individual permissions"
  244. echo " specified in @RESTRICT useless, as the permissions"
  245. echo " are stitched into file name as well"
  246. echo ""
  247. echo " --example show exampls"
  248. echo " --debug show processed lines, may not be fully functional"
  249. echo " --tea tea"
  250. exit
  251. ;;
  252. --example )
  253. echo ""
  254. echo "########################################"
  255. echo "@NAME_LIST Target Type"
  256. echo ">START"
  257. echo "[...]"
  258. echo "<END"
  259. echo "Target: USR/GRP"
  260. echo "Type: FILE/TEXT"
  261. echo ""
  262. echo "@NAME_LIST USR TEXT"
  263. echo ">START"
  264. echo "darren alice"
  265. echo "bob"
  266. echo "<END"
  267. echo ""
  268. echo "@NAME_LIST USR FILE"
  269. echo ">START"
  270. echo "namelist1"
  271. echo "namelist2"
  272. echo "<END"
  273. echo "########################################"
  274. echo "@STRAY [NO] RES Target Name Perm_type Permission [Perm_type Permission] [R] file"
  275. echo "Target: USR/GRP"
  276. echo "Perm_type: P, D"
  277. echo ""
  278. echo "@STRAY RES USR darren P --- D --- /usr/bin/su"
  279. echo "@STRAY RES GRP users P --- /usr/bin/su"
  280. echo "########################################"
  281. echo "@CHOWN Target Name [Target Name]"
  282. echo "file"
  283. echo "[...]"
  284. echo "<END"
  285. echo "Target: USER, GROUP"
  286. echo ""
  287. echo "@CHOWN USER darren GROUP users"
  288. echo "/home/darrenldl"
  289. echo "<END"
  290. echo "########################################"
  291. echo "@CHMOD TargetOperandPermission[,TargetOperandPermission]"
  292. echo "file"
  293. echo "[...]"
  294. echo "<END"
  295. echo "Target: u, g, o, a"
  296. echo "Operand: = + -"
  297. echo "Permission: blank or combination of r w x"
  298. echo ""
  299. echo "@CHMOD u=rwx,g=rx,o="
  300. echo "/usr/bin/su"
  301. echo "<END"
  302. echo "########################################"
  303. echo "@CHATTR [RECUR] [VERBOSE] [VERSION number] Attributes"
  304. echo "file"
  305. echo "[...]"
  306. echo "<END"
  307. echo "Attributes: Refer to man chattr"
  308. echo ""
  309. echo "@CHATTR +i"
  310. echo "/usr/bin/su"
  311. echo "<END"
  312. echo "########################################"
  313. echo "@APPEND"
  314. echo "text"
  315. echo "[...]"
  316. echo ">START"
  317. echo "file"
  318. echo "[...]"
  319. echo "<END"
  320. echo ""
  321. echo "@APPEND"
  322. echo "Hello"
  323. echo "Goodbye"
  324. echo ">START"
  325. echo "text_file"
  326. echo "<END"
  327. echo "########################################"
  328. echo "@INSERT"
  329. echo "text"
  330. echo "[...]"
  331. echo "@AFTER"
  332. echo "text"
  333. echo "[...]"
  334. echo ">START"
  335. echo "file"
  336. echo "[...]"
  337. echo "<END"
  338. echo ""
  339. echo "@INSERT"
  340. echo "Goodbye"
  341. echo "@AFTER"
  342. echo "Hello"
  343. echo ">START"
  344. echo "text_file"
  345. echo "<END"
  346. echo ""
  347. echo "@INSERT"
  348. echo "text"
  349. echo "[...]"
  350. echo "@LINE number"
  351. echo ">START"
  352. echo "file"
  353. echo "[...]"
  354. echo "<END"
  355. echo ""
  356. echo "@INSERT"
  357. echo "Hello"
  358. echo "@LINE 10"
  359. echo ">START"
  360. echo "text_file"
  361. echo "<END"
  362. echo "########################################"
  363. echo "@REPLACE"
  364. echo "text"
  365. echo "[...]"
  366. echo "@WITH"
  367. echo "text"
  368. echo "[...]"
  369. echo ">START"
  370. echo "file"
  371. echo "[...]"
  372. echo "<END"
  373. echo ""
  374. echo "@REPLACE"
  375. echo "Hello"
  376. echo "@WITH"
  377. echo "Goodbye"
  378. echo ">START"
  379. echo "text_file"
  380. echo "<END"
  381. echo "########################################"
  382. echo "@COMMAND"
  383. echo ">START"
  384. echo "command"
  385. echo "[...]"
  386. echo "<END"
  387. echo "########################################"
  388. echo "[!NO]"
  389. echo "@RESTRICT Target name"
  390. echo "[@RESTRICT Target name]"
  391. echo "[@EXCLUDE Target name]"
  392. echo "[@EXCLUDE Target name]"
  393. echo "Perm_type Permission"
  394. echo "[Perm_type Permission]"
  395. echo "[+RECUR]"
  396. echo ">START"
  397. echo "file"
  398. echo "[...]"
  399. echo "<END"
  400. echo "Target: USER, GROUP"
  401. echo "Perm_type: +PERM, +DPERM"
  402. echo "Permission: Combination of r w x -, length: 3 characters"
  403. echo ""
  404. echo "@RESTRICT USER darren alice bob"
  405. echo "@RESTRICT GROUP users http video"
  406. echo "@EXCLUDE USER bob"
  407. echo "@EXCLUDE GROUP http video"
  408. echo "+PERM ---"
  409. echo ">START"
  410. echo "/usr/bin/su"
  411. echo "<END"
  412. exit
  413. ;;
  414. --test )
  415. if (( $fl_I_t == 1 )); then
  416. echo " -t repeated"
  417. exit
  418. fi
  419. fl_I_t=1
  420. ;;
  421. --stat )
  422. if (( $fl_I_s == 1 )); then
  423. echo " -s repeated"
  424. exit
  425. fi
  426. fl_I_s=1
  427. ;;
  428. --commentedwarning | --cw )
  429. if (( $fl_I_cw_c == 1 )); then
  430. echo " --cw or --ncw has been specified"
  431. exit
  432. fi
  433. fl_I_cw_c=1
  434. char_escape_warn_cw=1
  435. ;;
  436. --nocommentedwarning | --ncw )
  437. if (( $fl_I_cw_c == 1 )); then
  438. echo " --cw or --ncw has been specified"
  439. exit
  440. fi
  441. fl_I_cw_c=1
  442. char_escape_warn_cw=0
  443. ;;
  444. --warning | --w )
  445. if (( $fl_I_w_c == 1 )); then
  446. echo " --w or --nw has been specified"
  447. exit
  448. fi
  449. fl_I_w_c=1
  450. char_escape_warn_w=1
  451. ;;
  452. --nowarning | --nw )
  453. if (( $fl_I_w_c == 1 )); then
  454. echo " --w or --nw has been specified"
  455. exit
  456. fi
  457. fl_I_w_c=1
  458. char_escape_warn_w=0
  459. ;;
  460. --filename_auto_stitch )
  461. if (( $fl_I_fnas_c == 1 )); then
  462. echo " --filename_auto_stitch repeated"
  463. exit
  464. fi
  465. fl_I_fnas_c=1
  466. filename_auto_stitch=1
  467. ;;
  468. --debug )
  469. if (( $fl_debug == 1 )); then
  470. echo " --debug repeated"
  471. exit
  472. fi
  473. fl_debug=1
  474. ;;
  475. --tea )
  476. echo "###################################"
  477. echo "# #"
  478. echo "# * * * #"
  479. echo "# * * * #"
  480. echo "# * * * #"
  481. echo "# * * * #"
  482. echo "# * * * #"
  483. echo "# * * * #"
  484. echo "# ## * * * ## #"
  485. echo "# #####...........## #"
  486. echo "# ## ## ## #"
  487. echo "# ## ## ## #"
  488. echo "# ## ## ## #"
  489. echo "# ##### ## #"
  490. echo "# ## ## #"
  491. echo "# ########### #"
  492. echo "# #"
  493. echo "# Tea. #"
  494. echo "# #"
  495. echo "###################################"
  496. exit
  497. ;;
  498. * ) echo "Invalid options"
  499. exit
  500. ;;
  501. esac
  502. if (( $fl_I_t == 1 )) && [[ (( $fl_I_a == 1 )) || (( $fl_I_g == 1 )) ]]; then
  503. echo "-t cannot be used with -a or -g"
  504. exit
  505. fi
  506. else if [[ "$temp" == -* ]]; then
  507. for (( j=1; j < ${#temp}; j++)); do
  508. case ${temp:$j:1} in
  509. a ) if (( $fl_I_a == 1 )); then
  510. echo " -a repeated"
  511. exit
  512. fi
  513. fl_I_a=1
  514. ;;
  515. d ) if (( $fl_I_d == 1 )); then
  516. echo " -d repeated"
  517. exit
  518. fi
  519. fl_I_d=1
  520. ;;
  521. g ) if (( $fl_I_g == 1 )); then
  522. echo " -g repeated"
  523. exit
  524. fi
  525. fl_I_g=1
  526. ;;
  527. h )
  528. echo "Usage : ./ezsetfacl.sh [OPTIONS] [file list]"
  529. echo ""
  530. echo "Options :"
  531. echo " -a, --apply apply rules"
  532. echo " -d, --timestamp prepend a line for data and time"
  533. echo " -g, --generate generate commands"
  534. echo " -h, --help show help message"
  535. echo " -t, --test check errors only"
  536. echo " -s, --stat show statistics"
  537. echo ""
  538. echo " --cw, --commentedwarning show commented warning text messages in generate mode,"
  539. echo " regardless of whether apply mode is chosen"
  540. echo " --ncw, --nocommentedwarning do not show commented warning (default) "
  541. echo " --w --warning show warning text messages(default),"
  542. echo " only when only apply mode is chosen"
  543. echo " --nw, --nowarning do not show warning text messages,"
  544. echo " only when only apply mode is chosen"
  545. echo " --filename_auto_stitch adds '\' automatically to file names with spaces if not already"
  546. echo " Warning: auto_stitch will render individual permissions"
  547. echo " specified in @RESTRICT useless, as the permissions"
  548. echo " are stitched into file name as well"
  549. echo ""
  550. echo " --example show exampls"
  551. echo " --debug show processed lines, may not be fully functional"
  552. echo " --tea tea"
  553. exit
  554. ;;
  555. t ) if (( $fl_I_t == 1 )); then
  556. echo " -t repeated"
  557. exit
  558. fi
  559. fl_I_t=1
  560. ;;
  561. s ) if (( $fl_I_s == 1 )); then
  562. echo " -s repeated"
  563. exit
  564. fi
  565. fl_I_s=1
  566. ;;
  567. * ) echo "Invalid options"
  568. exit
  569. ;;
  570. esac
  571. if (( $fl_I_t == 1 )) && [[ (( $fl_I_a == 1 )) || (( $fl_I_g == 1 )) ]]; then
  572. echo "-t cannot be used with -a or -g"
  573. exit
  574. fi
  575. done
  576. else
  577. if (( $fl_f_specified == 0 )); then
  578. filelist=${!i}
  579. fl_f_specified=1
  580. else
  581. echo "Please specify only one file list"
  582. exit
  583. fi
  584. fi
  585. fi
  586. done
  587.  
  588. if (( $fl_f_specified == 0 )); then
  589. echo "Please specify file list"
  590. exit
  591. fi
  592.  
  593. if (( $[ $fl_I_a + $fl_I_g + $fl_I_t + $fl_I_s] == 0 )); then
  594. echo "Please specify at least one action"
  595. exit
  596. fi
  597.  
  598. if (( $fl_I_s == 1 )) && (( $[ $fl_I_a + $fl_I_g + $fl_I_t ] == 0 )); then
  599. echo "Statistics option cannot be used alone, please specify -a, -g or -t"
  600. exit
  601. fi
  602.  
  603. fl_apply=$fl_I_a
  604. fl_gen=$fl_I_g
  605.  
  606. if [ ! -f "$filelist" ]; then
  607. echo "File list does not exist"
  608. exit
  609. fi
  610.  
  611. function char_escape { # char_escape line_raw
  612. local f__str=${!1}
  613. local f__str2="$1"
  614. if [[ $f__str =~ \* ]]; then
  615. f__str=$( echo "$f__str" | sed 's/\*/\\\*/g' )
  616. if (( $char_escape_warn_cw == 1 )); then
  617. echo "# Warning : $line_no : char_escape : wildcard detected, escaped character"
  618. fi
  619. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  620. echo "Warning : $line_no : char_escape : wildcard detected, escaped character"
  621. fi
  622. ((c_warn++))
  623. fi
  624. local i="$[${#f__str}-1]"
  625. local c=0
  626. if [[ ${f__str:$i:1} == '\' ]]; then
  627. for ((a = 0; a < $i; a++)); do
  628. if [[ ${f__str:$i-a:1} == '\' ]]; then
  629. ((c++))
  630. else
  631. break
  632. fi
  633. done
  634. if (( $c % 2 == 1 )); then
  635. f__str=$f__str'\'
  636. if (( $char_escape_warn_cw == 1 )); then
  637. echo "# Warning : $line_no : char_escape : trailing '\' detected, escaped character"
  638. fi
  639. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  640. echo "Warning : $line_no : char_escape : trailing '\' detected, escaped character"
  641. fi
  642. ((c_warn++))
  643. fi
  644. fi
  645. if [[ $f__str =~ '\a' ]]; then
  646. f__str=$( echo "$f__str" | sed 's/\\a/\\\\a/g' )
  647. if (( $char_escape_warn_cw == 1 )); then
  648. echo "# Warning : $line_no : char_escape : '\a' detected, escaped character"
  649. fi
  650. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  651. echo "Warning : $line_no : char_escape : '\a' detected, escaped character"
  652. fi
  653. ((c_warn++))
  654. fi
  655. if [[ $f__str =~ '\b' ]]; then
  656. f__str=$( echo "$f__str" | sed 's/\\b/\\\\b/g' )
  657. if (( $char_escape_warn_cw == 1 )); then
  658. echo "# Warning : $line_no : char_escape : '\b' detected, escaped character"
  659. fi
  660. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  661. echo "Warning : $line_no : char_escape : '\b' detected, escaped character"
  662. fi
  663. ((c_warn++))
  664. fi
  665. if [[ $f__str =~ '\c' ]]; then
  666. f__str=$( echo "$f__str" | sed 's/\\c/\\\\c/g' )
  667. if (( $char_escape_warn_cw == 1 )); then
  668. echo "# Warning : $line_no : char_escape : '\c' detected, escaped character"
  669. fi
  670. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  671. echo "Warning : $line_no : char_escape : '\c' detected, escaped character"
  672. fi
  673. ((c_warn++))
  674. fi
  675. if [[ $f__str =~ '\e' ]]; then
  676. f__str=$( echo "$f__str" | sed 's/\\e/\\\\e/g' )
  677. if (( $char_escape_warn_cw == 1 )); then
  678. echo "# Warning : $line_no : char_escape : '\e' detected, escaped character"
  679. fi
  680. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  681. echo "Warning : $line_no : char_escape : '\e' detected, escaped character"
  682. fi
  683. ((c_warn++))
  684. fi
  685. if [[ $f__str =~ '\f' ]]; then
  686. f__str=$( echo "$f__str" | sed 's/\\f/\\\\f/g' )
  687. if (( $char_escape_warn_cw == 1 )); then
  688. echo "# Warning : $line_no : char_escape : '\f' detected, escaped character"
  689. fi
  690. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  691. echo "Warning : $line_no : char_escape : '\f' detected, escaped character"
  692. fi
  693. ((c_warn++))
  694. fi
  695. if [[ $f__str =~ '\n' ]]; then
  696. f__str=$( echo "$f__str" | sed 's/\\n/\\\\n/g' )
  697. if (( $char_escape_warn_cw == 1 )); then
  698. echo "# Warning : $line_no : char_escape : '\n' detected, escaped character"
  699. fi
  700. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  701. echo "Warning : $line_no : char_escape : '\n' detected, escaped character"
  702. fi
  703. ((c_warn++))
  704. fi
  705. if [[ $f__str =~ '\r' ]]; then
  706. f__str=$( echo "$f__str" | sed 's/\\r/\\\\r/g' )
  707. if (( $char_escape_warn_cw == 1 )); then
  708. echo "# Warning : $line_no : char_escape : '\r' detected, escaped character"
  709. fi
  710. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  711. echo "Warning : $line_no : char_escape : '\r' detected, escaped character"
  712. fi
  713. ((c_warn++))
  714. fi
  715. if [[ $f__str =~ '\t' ]]; then
  716. f__str=$( echo "$f__str" | sed 's/\\t/\\\\t/g' )
  717. if (( $char_escape_warn_cw == 1 )); then
  718. echo "# Warning : $line_no : char_escape : '\t' detected, escaped character"
  719. fi
  720. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  721. echo "Warning : $line_no : char_escape : '\t' detected, escaped character"
  722. fi
  723. ((c_warn++))
  724. fi
  725. if [[ $f__str =~ '\v' ]]; then
  726. f__str=$( echo "$f__str" | sed 's/\\v/\\\\v/g' )
  727. if (( $char_escape_warn_cw == 1 )); then
  728. echo "# Warning : $line_no : char_escape : '\v' detected, escaped character"
  729. fi
  730. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  731. echo "Warning : $line_no : char_escape : '\v' detected, escaped character"
  732. fi
  733. ((c_warn++))
  734. fi
  735. eval $f__str2="'$f__str'"
  736. }
  737.  
  738. function char_escape_quiet { # char_escape_quiet line_raw
  739. local f__str=${!1}
  740. local f__str2="$1"
  741. if [[ $f__str =~ \* ]]; then
  742. f__str=$( echo "$f__str" | sed 's/\*/\\\*/g' )
  743. ((c_warn++))
  744. fi
  745. local i="$[${#f__str}-1]"
  746. local c=0
  747. if [[ ${f__str:$i:1} == '\' ]]; then
  748. for ((a = 0; a < $i; a++)); do
  749. if [[ ${f__str:$i-a:1} == '\' ]]; then
  750. ((c++))
  751. else
  752. break
  753. fi
  754. done
  755. if (( $c % 2 == 1 )); then
  756. f__str=$f__str'\'
  757. fi
  758. fi
  759. if [[ $f__str =~ '\a' ]]; then
  760. f__str=$( echo "$f__str" | sed 's/\\a/\\\\a/g' )
  761. ((c_warn++))
  762. fi
  763. if [[ $f__str =~ '\b' ]]; then
  764. f__str=$( echo "$f__str" | sed 's/\\b/\\\\b/g' )
  765. fi
  766. if [[ $f__str =~ '\c' ]]; then
  767. f__str=$( echo "$f__str" | sed 's/\\c/\\\\c/g' )
  768. fi
  769. if [[ $f__str =~ '\e' ]]; then
  770. f__str=$( echo "$f__str" | sed 's/\\e/\\\\e/g' )
  771. fi
  772. if [[ $f__str =~ '\f' ]]; then
  773. f__str=$( echo "$f__str" | sed 's/\\f/\\\\f/g' )
  774. fi
  775. if [[ $f__str =~ '\n' ]]; then
  776. f__str=$( echo "$f__str" | sed 's/\\n/\\\\n/g' )
  777. fi
  778. if [[ $f__str =~ '\r' ]]; then
  779. f__str=$( echo "$f__str" | sed 's/\\r/\\\\r/g' )
  780. fi
  781. if [[ $f__str =~ '\t' ]]; then
  782. f__str=$( echo "$f__str" | sed 's/\\t/\\\\t/g' )
  783. fi
  784. if [[ $f__str =~ '\v' ]]; then
  785. f__str=$( echo "$f__str" | sed 's/\\v/\\\\v/g' )
  786. fi
  787. eval $f__str2="'$f__str'"
  788. }
  789.  
  790. function char_deescape {
  791. local f__str=${!1}
  792. local f__str2="$1"
  793. if [[ $f__str =~ \\\* ]]; then # If line_raw contains wildcard,
  794. f__str=$( echo "$f__str" | sed 's/\\\*/*/g' ) # swap '*' to '\*' to avoid unexpected behavior
  795. fi
  796. if [[ $f__str =~ '\\a' ]]; then
  797. f__str=$( echo "$f__str" | sed 's/\\\\a/\\a/g' )
  798. fi
  799. if [[ $f__str =~ '\\b' ]]; then
  800. f__str=$( echo "$f__str" | sed 's/\\\\b/\\b/g' )
  801. fi
  802. if [[ $f__str =~ '\\c' ]]; then
  803. f__str=$( echo "$f__str" | sed 's/\\\\c/\\c/g' )
  804. fi
  805. if [[ $f__str =~ '\\e' ]]; then
  806. f__str=$( echo "$f__str" | sed 's/\\\\e/\\e/g' )
  807. fi
  808. if [[ $f__str =~ '\\f' ]]; then
  809. f__str=$( echo "$f__str" | sed 's/\\\\f/\\f/g' )
  810. fi
  811. if [[ $f__str =~ '\\n' ]]; then
  812. f__str=$( echo "$f__str" | sed 's/\\\\n/\\n/g' )
  813. fi
  814. if [[ $f__str =~ '\\r' ]]; then
  815. f__str=$( echo "$f__str" | sed 's/\\\\r/\\r/g' )
  816. fi
  817. if [[ $f__str =~ '\\t' ]]; then
  818. f__str=$( echo "$f__str" | sed 's/\\\\t/\\t/g' )
  819. fi
  820. if [[ $f__str =~ '\\v' ]]; then
  821. f__str=$( echo "$f__str" | sed 's/\\\\v/\\v/g' )
  822. fi
  823. eval $f__str2="'$f__str'"
  824. }
  825.  
  826. function char_deescape_echo { # char_deescape_echo line
  827. local f__str=${!1}
  828. if [[ $f__str =~ \\\* ]]; then # If line_raw contains wildcard,
  829. f__str=$( echo "$f__str" | sed 's/\\\*/*/g' ) # swap '*' to '\*' to avoid unexpected behavior
  830. fi
  831. if [[ $f__str =~ '\\a' ]]; then
  832. f__str=$( echo "$f__str" | sed 's/\\\\a/\\a/g' )
  833. fi
  834. if [[ $f__str =~ '\\b' ]]; then
  835. f__str=$( echo "$f__str" | sed 's/\\\\b/\\b/g' )
  836. fi
  837. if [[ $f__str =~ '\\c' ]]; then
  838. f__str=$( echo "$f__str" | sed 's/\\\\c/\\c/g' )
  839. fi
  840. if [[ $f__str =~ '\\e' ]]; then
  841. f__str=$( echo "$f__str" | sed 's/\\\\e/\\e/g' )
  842. fi
  843. if [[ $f__str =~ '\\f' ]]; then
  844. f__str=$( echo "$f__str" | sed 's/\\\\f/\\f/g' )
  845. fi
  846. if [[ $f__str =~ '\\n' ]]; then
  847. f__str=$( echo "$f__str" | sed 's/\\\\n/\\n/g' )
  848. fi
  849. if [[ $f__str =~ '\\r' ]]; then
  850. f__str=$( echo "$f__str" | sed 's/\\\\r/\\r/g' )
  851. fi
  852. if [[ $f__str =~ '\\t' ]]; then
  853. f__str=$( echo "$f__str" | sed 's/\\\\t/\\t/g' )
  854. fi
  855. if [[ $f__str =~ '\\v' ]]; then
  856. f__str=$( echo "$f__str" | sed 's/\\\\v/\\v/g' )
  857. fi
  858. echo -E $f__str
  859. }
  860.  
  861. function perm_check { # perm_check string flag
  862. local f__str="$1"
  863. local f__flag="$2"
  864. if [[ $f__str =~ ^[0-9]+$ ]]; then # Check if permission number is used
  865. if (( $f__str > 7 || $f__str < 0 )); then
  866. # Invalid number
  867. eval $f__flag="'1'"
  868. fi
  869. else
  870. if (( ${#f__str} != 3 )); then # Check length of f__string, which should be 3 characters long
  871. # Invalid string
  872. eval $f__flag="'2'"
  873. else
  874. if [[ ${f__str:0:1} == 'r' || ${f__str:0:1} == '-' ]]; then
  875. if [[ ${f__str:1:1} == 'w' || ${f__str:1:1} == '-' ]]; then
  876. if ! [[ ${f__str:2:1} == 'x' || ${f__str:2:1} == '-' ]]; then
  877. # Invalid f__string
  878. eval $f__flag="'2'"
  879. fi
  880. else
  881. # Invalid f__string
  882. eval $f__flag="'2'"
  883. fi
  884. else
  885. # Invalid f__string
  886. eval $f__flag="'2'"
  887. fi
  888. fi
  889. fi
  890. }
  891.  
  892. function perm_set { # perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no perm file fl_D fl_R fl_NOALL fl_apply fl_gen
  893. local f__users=("${!1}")
  894. local f__groups=("${!2}")
  895. local f__fl_u=("${!3}")
  896. local f__fl_g=("${!4}")
  897. local f__fl_no=${!5}
  898. local f__perm=${!6}
  899. local f__file=${!7}
  900. local f__fl_D=${!8}
  901. local f__fl_R=${!9}
  902. local f__fl_NOALL=${!10}
  903. local f__fl_apply=${!11}
  904. local f__fl_gen=${!12}
  905. if (( $f__fl_NOALL == 0 )); then
  906. for (( a=0; a < ${#f__users[@]}; a++ )); do # Check if user is marked to be processed
  907. if (( ${f__fl_u[$a]} == 1 )); then
  908. if (( $f__fl_no == 0 )); then
  909. if (( $f__fl_D == 0 )); then
  910. if (( $f__fl_R == 0 )); then
  911. if (( $f__fl_apply == 1 )); then
  912. setfacl -m u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)
  913. else if (( $f__fl_gen == 1 )); then
  914. echo "setfacl -m u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  915. fi
  916. fi
  917. else if (( $f__fl_apply == 1 )); then
  918. setfacl -Rm u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)
  919. else if (( $f__fl_gen == 1 )); then
  920. echo "setfacl -Rm u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  921. fi
  922. fi
  923. fi
  924. else
  925. if (( $f__fl_R == 0 )); then
  926. if (( $f__fl_apply == 1 )); then
  927. setfacl -m d:u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)
  928. else if (( $f__fl_gen == 1 )); then
  929. echo "setfacl -m d:u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  930. fi
  931. fi
  932. else if (( $f__fl_apply == 1 )); then
  933. setfacl -Rm d:u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)
  934. else if (( $f__fl_gen == 1 )); then
  935. echo "setfacl -Rm d:u:${f__users[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  936. fi
  937. fi
  938. fi
  939. fi
  940. else
  941. if (( $f__fl_D == 0 )); then
  942. if (( $f__fl_R == 0 )); then
  943. if (( $f__fl_apply == 1 )); then
  944. setfacl -x u:${f__users[$a]} -- $(char_deescape_echo f__file)
  945. else if (( $f__fl_gen == 1 )); then
  946. echo "setfacl -x u:${f__users[$a]} -- $(char_deescape_echo f__file)"
  947. fi
  948. fi
  949. else if (( $f__fl_apply == 1 )); then
  950. setfacl -Rx u:${f__users[$a]} -- $(char_deescape_echo f__file)
  951. else if (( $f__fl_gen == 1 )); then
  952. echo "setfacl -Rx u:${f__users[$a]} -- $(char_deescape_echo f__file)"
  953. fi
  954. fi
  955. fi
  956. else
  957. if (( $f__fl_R == 0 )); then
  958. if (( $f__fl_apply == 1 )); then
  959. setfacl -x d:u:${f__users[$a]} -- $(char_deescape_echo f__file)
  960. else if (( $f__fl_gen == 1 )); then
  961. echo "setfacl -x d:u:${f__users[$a]} -- $(char_deescape_echo f__file)"
  962. fi
  963. fi
  964. else if (( $f__fl_apply == 1 )); then
  965. setfacl -Rx d:u:${f__users[$a]} -- $(char_deescape_echo f__file)
  966. else if (( $f__fl_gen == 1 )); then
  967. echo "setfacl -Rx d:u:${f__users[$a]} -- $(char_deescape_echo f__file)"
  968. fi
  969. fi
  970. fi
  971. fi
  972. fi
  973. fi
  974. done
  975. for (( a=0; a < ${#f__groups[@]}; a++ )); do # Check if group is marked to be processed
  976. if (( ${f__fl_g[$a]} == 1 )); then
  977. if (( $f__fl_no == 0 )); then
  978. if (( $f__fl_D == 0 )); then
  979. if (( $f__fl_R == 0 )); then
  980. if (( $f__fl_apply == 1 )); then
  981. setfacl -m g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)
  982. else if (( $f__fl_gen == 1 )); then
  983. echo "setfacl -m g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  984. fi
  985. fi
  986. else if (( $f__fl_apply == 1 )); then
  987. setfacl -Rm g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)
  988. else if (( $f__fl_gen == 1 )); then
  989. echo "setfacl -Rm g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  990. fi
  991. fi
  992. fi
  993. else
  994. if (( $f__fl_R == 0 )); then
  995. if (( $f__fl_apply == 1 )); then
  996. setfacl -m d:g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)
  997. else if (( $f__fl_gen == 1 )); then
  998. echo "setfacl -m d:g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  999. fi
  1000. fi
  1001. else if (( $f__fl_apply == 1 )); then
  1002. setfacl -Rm d:g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)
  1003. else if (( $f__fl_gen == 1 )); then
  1004. echo "setfacl -Rm d:g:${f__groups[$a]}:$f__perm -- $(char_deescape_echo f__file)"
  1005. fi
  1006. fi
  1007. fi
  1008. fi
  1009. else
  1010. if (( $f__fl_D == 0 )); then
  1011. if (( $f__fl_R == 0 )); then
  1012. if (( $f__fl_apply == 1 )); then
  1013. setfacl -x g:${f__groups[$a]} -- $(char_deescape_echo f__file)
  1014. else if (( $f__fl_gen == 1 )); then
  1015. echo "setfacl -x g:${f__groups[$a]} -- $(char_deescape_echo f__file)"
  1016. fi
  1017. fi
  1018. else if (( $f__fl_apply == 1 )); then
  1019. setfacl -Rx g:${f__groups[$a]} -- $(char_deescape_echo f__file)
  1020. else if (( $f__fl_gen == 1 )); then
  1021. echo "setfacl -Rx g:${f__groups[$a]} -- $(char_deescape_echo f__file)"
  1022. fi
  1023. fi
  1024. fi
  1025. else
  1026. if (( $f__fl_R == 0 )); then
  1027. if (( $f__fl_apply == 1 )); then
  1028. setfacl -x d:g:${f__groups[$a]} -- $(char_deescape_echo f__file)
  1029. else if (( $f__fl_gen == 1 )); then
  1030. echo "setfacl -x d:g:${f__groups[$a]} -- $(char_deescape_echo f__file)"
  1031. fi
  1032. fi
  1033. else if (( $f__fl_apply == 1 )); then
  1034. setfacl -Rx d:g:${f__groups[$a]} -- $(char_deescape_echo f__file)
  1035. else if (( $f__fl_gen == 1 )); then
  1036. echo "setfacl -Rx d:g:${f__groups[$a]} -- $(char_deescape_echo f__file)"
  1037. fi
  1038. fi
  1039. fi
  1040. fi
  1041. fi
  1042. fi
  1043. done
  1044. else
  1045. if (( $f__fl_apply == 1 )); then
  1046. setfacl -b -- $(char_deescape_echo f__file)
  1047. else if (( $f__fl_gen == 1 )); then
  1048. echo "setfacl -b -- $(char_deescape_echo f__file)"
  1049. fi
  1050. fi
  1051. fi
  1052. }
  1053.  
  1054. function check_end {
  1055. local f__line_no=0
  1056. local f__temp_line_no=$[$line_no+1]
  1057. local f__line_raw=""
  1058. local f__line=()
  1059. local f__i=0
  1060. local f__word=""
  1061. while read -r f__line_raw; do
  1062. if [[ ($f__line_raw =~ ^$ || -z $f__line_raw || $f__line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  1063. ((f__temp_line_no++))
  1064. continue # If so, ignore line, check next line, still add line number though
  1065. fi
  1066. char_escape_quiet f__line_raw
  1067. f__i=0
  1068. f__line=() # Initialise primary line buffer
  1069. for f__word in $f__line_raw; do # Validate each word in line
  1070. if [[ $f__word == \#* || $f__word == '#' ]]; then # Ignore comments
  1071. # If word starts with '#', stop reading (probably is a comment)
  1072. break
  1073. fi
  1074. f__line[$f__i]="$f__word" # Push words to line[]
  1075. ((f__i++))
  1076. done
  1077. case ${f__line[0]} in
  1078. "@NAME_LIST")
  1079. break
  1080. ;;
  1081. "@STRAY" )
  1082. break
  1083. ;;
  1084. "@CHOWN" )
  1085. break
  1086. ;;
  1087. "@CHMOD" )
  1088. break
  1089. ;;
  1090. "@CHATTR" )
  1091. break
  1092. ;;
  1093. "@APPEND" )
  1094. break
  1095. ;;
  1096. "@INSERT" )
  1097. break
  1098. ;;
  1099. "@REPLACE" )
  1100. break
  1101. ;;
  1102. "@COMMAND" )
  1103. break
  1104. ;;
  1105. "!NO" )
  1106. break
  1107. ;;
  1108. "@RESTRICT" )
  1109. break
  1110. ;;
  1111. "@EXCLUDE" )
  1112. break
  1113. ;;
  1114. "+PERM" )
  1115. break
  1116. ;;
  1117. "+DPERM" )
  1118. break
  1119. ;;
  1120. "+RECUR" )
  1121. break
  1122. ;;
  1123. ">START" )
  1124. break
  1125. ;;
  1126. "<END" )
  1127. f__line_no=$f__temp_line_no
  1128. ((f__temp_line_no++))
  1129. ;;
  1130. * )
  1131. ((f__temp_line_no++))
  1132. ;;
  1133. esac
  1134. done < <(cat "$filelist" | sed -n "$[$line_no+1]"',$p')
  1135. echo $f__line_no
  1136. }
  1137.  
  1138. function check_after {
  1139. local f__line_no=0
  1140. local f__temp_line_no=$[$line_no+1]
  1141. local f__line_raw=""
  1142. local f__line=()
  1143. local f__i=0
  1144. local f__word=""
  1145. while read -r f__line_raw; do
  1146. if [[ ($f__line_raw =~ ^$ || -z $f__line_raw || $f__line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  1147. ((f__temp_line_no++))
  1148. continue # If so, ignore line, check next line, still add line number though
  1149. fi
  1150. char_escape_quiet f__line_raw
  1151. f__i=0
  1152. f__line=() # Initialise primary line buffer
  1153. for f__word in $f__line_raw; do # Validate each word in line
  1154. if [[ $f__word == \#* || $f__word == '#' ]]; then # Ignore comments
  1155. # If word starts with '#', stop reading (probably is a comment)
  1156. break
  1157. fi
  1158. f__line[$f__i]="$f__word" # Push words to line[]
  1159. ((f__i++))
  1160. done
  1161. case ${f__line[0]} in
  1162. "@INSERT")
  1163. break
  1164. ;;
  1165. "@LINE" )
  1166. break
  1167. ;;
  1168. "<END" )
  1169. f__line_no=$f__temp_line_no
  1170. ((f__temp_line_no++))
  1171. ;;
  1172. * )
  1173. ((f__temp_line_no++))
  1174. ;;
  1175. esac
  1176. done < <(cat "$filelist" | sed -n "$[$line_no+1]"',$p')
  1177. echo $f__line_no
  1178. }
  1179.  
  1180. function check_with {
  1181. local f__line_no=0
  1182. local f__temp_line_no=$[$line_no+1]
  1183. local f__line_raw=""
  1184. local f__line=()
  1185. local f__i=0
  1186. local f__word=""
  1187. while read -r f__line_raw; do
  1188. if [[ ($f__line_raw =~ ^$ || -z $f__line_raw || $f__line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  1189. ((f__temp_line_no++))
  1190. continue # If so, ignore line, check next line, still add line number though
  1191. fi
  1192. char_escape_quiet f__line_raw
  1193. f__i=0
  1194. f__line=() # Initialise primary line buffer
  1195. for f__word in $f__line_raw; do # Validate each word in line
  1196. if [[ $f__word == \#* || $f__word == '#' ]]; then # Ignore comments
  1197. # If word starts with '#', stop reading (probably is a comment)
  1198. break
  1199. fi
  1200. f__line[$f__i]="$f__word" # Push words to line[]
  1201. ((f__i++))
  1202. done
  1203. case ${f__line[0]} in
  1204. "@REPLACE")
  1205. break
  1206. ;;
  1207. "<END" )
  1208. f__line_no=$f__temp_line_no
  1209. ((f__temp_line_no++))
  1210. ;;
  1211. * )
  1212. ((f__temp_line_no++))
  1213. ;;
  1214. esac
  1215. done < <(cat "$filelist" | sed -n "$[$line_no+1]"',$p')
  1216. echo $f__line_no
  1217. }
  1218.  
  1219. function filename_stitch { # filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  1220. local f__line=("${!1}")
  1221. local f__str="$2"
  1222. local f__count="$3"
  1223. local f__error="$4"
  1224. local f__stitch_c=0
  1225. local f__stitch_string=""
  1226. if (( ${#f__line[@]} > 1 )); then
  1227. for (( i=0; i < ${#f__line[@]}; i++)); do
  1228. if [[ ${f__line[$i]} == *\\ ]]; then
  1229. f__stitch_string+=${f__line[$i]}' '
  1230. ((f__stitch_c++))
  1231. else
  1232. if (( $i > 0 )); then
  1233. if [[ ${f__line[$[$i-1]]} == *\\ ]]; then
  1234. f__stitch_string+=${f__line[$i]}
  1235. ((f__stitch_c++))
  1236. else
  1237. if (( $filename_auto_stitch == 1 )); then
  1238. f__stitch_string+='\ '
  1239. f__stitch_string+=${f__line[$i]}
  1240. ((f__stitch_c++))
  1241. if (( $char_escape_warn_cw == 1 )); then
  1242. echo "# Warning : $line_no : Detected missing '\' in file name, name stitched"
  1243. fi
  1244. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  1245. echo "Warning : $line_no : Detected missing '\' in file name, name stitched"
  1246. fi
  1247. fi
  1248. fi
  1249. fi
  1250. if (( $i == 0 )); then
  1251. if (( $filename_auto_stitch == 1 )); then
  1252. f__stitch_string+='\ '
  1253. f__stitch_string+=${f__line[$i]}
  1254. ((f__stitch_c++))
  1255. if (( $char_escape_warn_cw == 1 )); then
  1256. echo "# Warning : $line_no : Detected missing '\' in file name, name stitched"
  1257. fi
  1258. if (( $char_escape_warn_w == 1 )) && (( (( $fl_apply == 1 )) || (( $fl_I_t == 1 )) )) && (( $fl_gen == 0 )); then
  1259. echo "Warning : $line_no : Detected missing '\' in file name, name stitched"
  1260. fi
  1261. else
  1262. break
  1263. fi
  1264. fi
  1265. fi
  1266. done
  1267. fi
  1268. if (( $f__stitch_c == 0 )); then
  1269. f__stitch_c=1
  1270. f__stitch_string=${f__line[0]}
  1271. fi
  1272. eval $f__str="'$f__stitch_string'"
  1273. eval $f__count="'$f__stitch_c'"
  1274. }
  1275.  
  1276. function filename_stitch_quiet { # filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  1277. local f__line=("${!1}")
  1278. local f__str="$2"
  1279. local f__count="$3"
  1280. local f__error="$4"
  1281. local f__stitch_c=0
  1282. local f__stitch_string=""
  1283. if (( ${#f__line[@]} > 1 )); then
  1284. for (( i=0; i < ${#f__line[@]}; i++)); do
  1285. if [[ ${f__line[$i]} == *\\ ]]; then
  1286. f__stitch_string+=${f__line[$i]}' '
  1287. ((f__stitch_c++))
  1288. else
  1289. if (( $i > 0 )); then
  1290. if [[ ${f__line[$[$i-1]]} == *\\ ]]; then
  1291. f__stitch_string+=${f__line[$i]}
  1292. ((f__stitch_c++))
  1293. else
  1294. if (( $filename_auto_stitch == 1 )); then
  1295. f__stitch_string+='\ '
  1296. f__stitch_string+=${f__line[$i]}
  1297. ((f__stitch_c++))
  1298. fi
  1299. fi
  1300. fi
  1301. if (( $i == 0 )); then
  1302. if (( $filename_auto_stitch == 1 )); then
  1303. f__stitch_string+='\ '
  1304. f__stitch_string+=${f__line[$i]}
  1305. ((f__stitch_c++))
  1306. else
  1307. break
  1308. fi
  1309. fi
  1310. fi
  1311. done
  1312. fi
  1313. if (( $f__stitch_c == 0 )); then
  1314. f__stitch_c=1
  1315. f__stitch_string=${f__line[0]}
  1316. fi
  1317. eval $f__str="'$f__stitch_string'"
  1318. eval $f__count="'$f__stitch_c'"
  1319. }
  1320.  
  1321. if (( $fl_I_g == 1 )); then
  1322. echo '#!/bin/bash'
  1323. fi
  1324.  
  1325. while read -r line_raw; do
  1326. if [[ ($line_raw =~ ^$ || -z $line_raw || $line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  1327. ((line_no++))
  1328. continue # If so, ignore line, check next line, still add line number though
  1329. fi
  1330. for (( i=0; i < ${#users[@]}; i++ )); do # Initialise 'users' array
  1331. fl_u_valid_line[$i]=0
  1332. fl_u_checked[$i]=0
  1333. done
  1334. for (( i=0; i < ${#groups[@]}; i++ )); do # Initialise 'groups' array
  1335. fl_g_valid_line[$i]=0
  1336. fl_g_checked[$i]=0
  1337. done
  1338. char_escape line_raw
  1339. if (( $fl_debug == 1 )); then
  1340. echo "$line_no : $line_raw"
  1341. fi
  1342. i=0
  1343. line=() # Initialise primary line buffer
  1344. for word in $line_raw; do # Validate each word in line
  1345. if [[ $word == \#* || $word == '#' ]]; then # Ignore comments
  1346. # If word starts with '#', stop reading (probably is a comment)
  1347. break
  1348. fi
  1349. line[$i]="$word" # Push words to line[]
  1350. ((i++))
  1351. done
  1352. if (( $fl_f_list == 0 )) && (( $fl_w_list == 0 )); then
  1353. case ${line[0]} in # Analyse 1st word
  1354. "@NAME_LIST" )
  1355. if (( $fl_no == 1 )); then
  1356. echo "$line_no : NO cannot be used with @NAME_LIST"
  1357. c_error=1
  1358. break
  1359. fi
  1360. if !(( $fl_o == 0 )); then
  1361. echo "$line_no : @NAME_LIST : Entries must be outside a ACL block"
  1362. c_error=1
  1363. break
  1364. fi
  1365. fl_o=1
  1366. if (( ${#line[@]} > 3 )); then
  1367. echo "$line_no : @STRAY : Too many operands"
  1368. c_error=1
  1369. break
  1370. fi
  1371. if (( ${#line[@]} < 3 )); then # Per file, per user
  1372. echo "$line_no : @STRAY : Too few operands"
  1373. c_error=1
  1374. break
  1375. fi
  1376. for (( i=1; i < ${#line[@]}; i++ )); do
  1377. case ${line[$i]} in
  1378. "USR" ) fl_nm_list_ug=0
  1379. if (( fl_o != 1 )); then
  1380. echo "$line_no : @NAME_LIST : USR/GRP specified already"
  1381. c_error=1
  1382. break
  1383. fi
  1384. fl_o=2
  1385. ;;
  1386. "GRP" ) fl_nm_list_ug=1
  1387. if (( fl_o != 1 )); then
  1388. echo "$line_no : @NAME_LIST : USR/GRP specified already"
  1389. c_error=1
  1390. break
  1391. fi
  1392. fl_o=2
  1393. ;;
  1394. "FILE" )fl_nm_list_ft=0
  1395. if (( fl_o != 2 )); then
  1396. echo "$line_no : @NAME_LIST : FILE must be placed after USR/GRP"
  1397. c_error=1
  1398. break
  1399. fi
  1400. fl_o=3
  1401. ;;
  1402. "TEXT" )fl_nm_list_ft=1
  1403. if (( fl_o != 2 )); then
  1404. echo "$line_no : @NAME_LIST : TEXT must be placed after USR/GRP"
  1405. c_error=1
  1406. break
  1407. fi
  1408. fl_o=3
  1409. ;;
  1410. * ) echo "$line_no : @NAME_LIST : Invalid operands"
  1411. c_error=1
  1412. break
  1413. ;;
  1414. esac
  1415. done
  1416. fl_start_type=5
  1417. fl_nm_list_specified=1
  1418. ;;
  1419. "@STRAY" ) if (( $fl_no == 1 )); then
  1420. echo "$line_no : NO cannot be used with @STRAY"
  1421. c_error=1
  1422. break
  1423. fi
  1424. if !(( $fl_o == 0 )); then
  1425. echo "$line_no : @STRAY : Entries must be outside a ACL block"
  1426. c_error=1
  1427. break
  1428. fi
  1429. if (( ${#line[@]} == 1 )); then # Per file, per user
  1430. echo "$line_no : @STRAY : Too few operands"
  1431. c_error=1
  1432. break
  1433. fi
  1434. for (( i=1; i < ${#line[@]}; i++ )); do
  1435. case ${line[$i]} in
  1436. "NO" ) if !(( $fl_o == 0 )); then
  1437. echo "$line_no : @STRAY : NO should be before any other operands"
  1438. c_error=1
  1439. break
  1440. fi
  1441. if (( $fl_no == 1 )); then
  1442. echo "$line_no : @STRAY : NO cannot be repeated"
  1443. c_error=1
  1444. break
  1445. fi
  1446. fl_no=1
  1447. ;;
  1448. RES )
  1449. stray_file_index=0
  1450. fl_o=1
  1451. ;;
  1452. USR ) if (( $fl_o == 0 )); then
  1453. echo "$line_no : @STRAY : RES must be specified before USR"
  1454. c_error=1
  1455. break
  1456. else if (( $fl_o == 2 )); then
  1457. echo "$line_no : @STRAY : USR/GRP can only be specified once"
  1458. fi
  1459. fi
  1460. fl_o=2
  1461. ;;
  1462. GRP ) if (( $fl_o == 0 )); then
  1463. echo "$line_no : @STRAY : RES must be specified before USR"
  1464. c_error=1
  1465. break
  1466. else if (( $fl_o == 2 )); then
  1467. echo "$line_no : @STRAY : USR/GRP can only be specified once"
  1468. fi
  1469. fi
  1470. fl_o=2
  1471. ;;
  1472. P ) if !(( $fl_o > 2 )) && !(( $fl_o < 4 )); then
  1473. echo "$line_no : @STRAY : Missing USR before P"
  1474. c_error=1
  1475. break
  1476. fi
  1477. if (( $fl_P == 1 )); then
  1478. echo "$line_no : @STRAY : P cannot be repeated"
  1479. c_error=1
  1480. break
  1481. fi
  1482. fl_P=1
  1483. fl_o=3
  1484. stray_file_index=$i+2
  1485. ;;
  1486. D ) if !(( $fl_o > 2 )) && !(( $fl_o < 4 )); then
  1487. echo "$line_no : @STRAY : Missing USR before D"
  1488. c_error=1
  1489. break
  1490. fi
  1491. if (( $fl_D == 1 )); then
  1492. echo "$line_no : @STRAY : D cannot be repeated"
  1493. c_error=1
  1494. break
  1495. fi
  1496. fl_D=1
  1497. fl_o=3
  1498. stray_file_index=$i+2
  1499. ;;
  1500. R ) if !(( $fl_o > 2 )) && !(( $fl_o < 4 )); then
  1501. echo "$line_no : @STRAY : Missing USR before R"
  1502. c_error=1
  1503. break
  1504. fi
  1505. if (( $fl_R == 1 )); then
  1506. echo "$line_no : @STRAY : R should not be repeated"
  1507. c_error=1
  1508. break
  1509. fi
  1510. fl_R=1
  1511. fl_o=3
  1512. stray_file_index=$i+1
  1513. ;;
  1514. * ) if [[ ${line[$i-1]} == "USR" ]]; then
  1515. for (( j=0; j < ${#users[@]}; j++ )); do
  1516. if [[ ${line[$i]} == ${users[$j]} ]]; then
  1517. fl_u_check=1
  1518. break
  1519. fi
  1520. done
  1521. if [[ ${line[$i]} == "ALL" ]]; then
  1522. echo "$line_no : @STRAY : ALL is disabled"
  1523. c_error=1
  1524. break
  1525. fi
  1526. if (( $fl_u_check == 0 )); then
  1527. echo "$line_no : @STRAY : Invalid user"
  1528. c_error=1
  1529. break
  1530. fi
  1531. fl_stray_c=1
  1532. fi
  1533. if [[ ${line[$i-1]} == "GRP" ]]; then
  1534. for (( j=0; j < ${#groups[@]}; j++)); do
  1535. if [[ ${line[$i]} == ${groups[$j]} ]]; then
  1536. fl_g_check=1
  1537. break
  1538. fi
  1539. done
  1540. if [[ ${line[$i]} == "ALL" ]]; then
  1541. echo "$line_no : @STRAY : ALL is disabled"
  1542. c_error=1
  1543. break
  1544. fi
  1545. if (( $fl_g_check == 0 )); then
  1546. echo "$line_no : @STRAY : Invalid group"
  1547. c_error=1
  1548. break
  1549. fi
  1550. fl_stray_c=1
  1551. fi
  1552. if (( $fl_o != 3 )) && (( $fl_stray_c == 0 )); then
  1553. if (( $fl_no == 0 )); then
  1554. echo "$line_no : @STRAY : Invalid operand"
  1555. c_error=1
  1556. break
  1557. else
  1558. if (( $i != $[${#line[@]}-1] )); then
  1559. echo "$line_no : @STRAY : Invalid operand"
  1560. c_error=1
  1561. break
  1562. fi
  1563. fi
  1564. fi
  1565. if [[ ${line[$i-1]} == "P" ]] || [[ ${line[$i-1]} == "D" ]]; then
  1566. perm_check ${line[$i]} fl_perm_check
  1567. if (( $fl_perm_check == 1 )); then
  1568. echo "$line_no : @STRAY : Invalid permission number"
  1569. c_error=1
  1570. break
  1571. else if (( $fl_perm_check == 2 )); then
  1572. echo "$line_no : @STRAY : Invalid permission string"
  1573. c_error=1
  1574. break
  1575. fi
  1576. fi
  1577. fl_stray_c=1
  1578. fi
  1579. if (( $fl_o != 3 )) && (( $i == $[${#line[@]}-1] )) && (( $fl_stray_c == 0 )) && (( $fl_no == 0 )); then
  1580. echo "$line_no : @STRAY : Invalid operand"
  1581. c_error=1
  1582. break
  1583. fi
  1584. if (( $fl_o == 3)) && (( $i == $[${#line[@]}-1] )) && (( $fl_stray_c == 0 )) && (( $fl_no == 0 )); then
  1585. if (( $[$fl_P + $fl_D] == 0 )) && (( $fl_no == 0 )); then
  1586. echo "$line_no : @STRAY : Must specify P or D when NO is not used"
  1587. c_error=1
  1588. break
  1589. fi
  1590. fl_o=0
  1591. fl_P=0
  1592. fl_D=0
  1593. fl_R=0
  1594. fi
  1595. fl_stray_c=0
  1596. ;;
  1597. esac
  1598. done
  1599. j=0
  1600. for (( i=$stray_file_index; i < ${#line[@]}; i++ )); do
  1601. stray_file_array[j]=${line[$i]}
  1602. ((j++))
  1603. done
  1604. filename_stitch stray_file_array[@] file_name_stitch_string file_name_stitch_c c_error
  1605. if (( $[${#stray_file_array[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  1606. echo "$line_no : file too many arguments"
  1607. c_error=1
  1608. break
  1609. fi
  1610. if (( $fl_o != 0 )) && (( $c_error == 0 )) && (( $fl_no == 0 )); then
  1611. echo "$line_no : @STRAY : Incomplete entry"
  1612. c_error=1
  1613. break
  1614. fi
  1615. fl_o=0
  1616. fl_no=0
  1617. ((file_no++))
  1618. ((stray_no++))
  1619. ;;
  1620. "@CHOWN" )
  1621. if (( $fl_no == 1 )); then
  1622. echo "$line_no : !NO cannot be used with @CHOWN"
  1623. c_error=1
  1624. break
  1625. fi
  1626. if (( $fl_o != 0 )); then
  1627. echo "$line_no : @CHOWN : Inside another structure"
  1628. c_error=1
  1629. break
  1630. fi
  1631. fl_o=1
  1632. if (( ${#line[@]} > 5 )); then
  1633. echo "$line_no : @CHOWN : Too many operands"
  1634. c_error=1
  1635. break
  1636. fi
  1637. if (( ${#line[@]} < 3 )); then
  1638. echo "$line_no : @CHOWN : Too few operands"
  1639. c_error=1
  1640. break
  1641. fi
  1642. for (( i=1; i < ${#line[@]}; i++ )); do
  1643. case ${line[$i]} in
  1644. USER ) if (( $fl_chown_u_c != 0 )); then
  1645. echo "$line_no : @CHOWN : USER cannot be repeated"
  1646. c_error=1
  1647. break
  1648. fi
  1649. fl_o=1
  1650. fl_chown_u_c=1
  1651. ;;
  1652. GROUP ) if (( $fl_chown_g_c != 0 )); then
  1653. echo "$line_no : @CHOWN : GROUP cannot be repeated"
  1654. c_error=1
  1655. break
  1656. fi
  1657. fl_o=1
  1658. fl_chown_g_c=1
  1659. ;;
  1660. * ) if [[ ${line[$i-1]} == "USER" ]]; then
  1661. fl_chown_c=1
  1662. fl_chown_u_c=2
  1663. fi
  1664. if [[ ${line[$i-1]} == "GROUP" ]]; then
  1665. fl_chown_c=1
  1666. fl_chown_g_c=2
  1667. fi
  1668. if (( $fl_o == 0 )); then
  1669. echo "$line_no : @CHOWN : No target specified"
  1670. c_error=1
  1671. break
  1672. fi
  1673. if (( $fl_chown_c == 0 )); then
  1674. echo "$line_no : @CHOWN : Invalid operand"
  1675. c_error=1
  1676. break
  1677. fi
  1678. fl_chown_c=0
  1679. ;;
  1680. esac
  1681. done
  1682. if (($c_error == 1)); then
  1683. exit
  1684. fi
  1685. if (( $fl_chown_u_c == 1 )) || (( $fl_chown_g_c == 1 )); then
  1686. echo "$line_no : @CHOWN : Missing user/group name"
  1687. c_error=1
  1688. break
  1689. fi
  1690. fl_f_list=1
  1691. fl_f_list_type=1
  1692. end_line_no=$(check_end)
  1693. ;;
  1694. "@CHMOD" )
  1695. if (( $fl_no == 1 )); then
  1696. echo "$line_no : !NO cannot be used with @CHMOD"
  1697. c_error=1
  1698. break
  1699. fi
  1700. if (( $fl_o != 0 )); then
  1701. echo "$line_no : @CHMOD : Inside another structure"
  1702. c_error=1
  1703. break
  1704. fi
  1705. fl_o=1
  1706. if (( ${#line[@]} > 2 )); then
  1707. echo "$line_no : @CHMOD : Too many operands"
  1708. c_error=1
  1709. break
  1710. fi
  1711. if (( ${#line[@]} < 2 )); then
  1712. echo "$line_no : @CHMOD : Too few operands"
  1713. c_error=1
  1714. break
  1715. fi
  1716. if [[ ${line[1]} == ^[0-9]+$ ]]; then # Check if permission number is used
  1717. if (( ${#line[1]} != 3 )); then
  1718. echo "$line_no : @CHMOD : Invalid permission number"
  1719. c_error=1
  1720. break
  1721. fi
  1722. for (( i=0; i < 3; i++ )); do
  1723. if (( ${line[1]:$i:1} > 7 || ${line[1]:$i:1} < 0 )); then
  1724. echo "$line_no : @CHMOD : Invalid permission number"
  1725. c_error=1
  1726. break
  1727. fi
  1728. done
  1729. else
  1730. for (( i=0; i < ${#line[1]}; i++ )); do
  1731. case ${line[1]:$i:1} in
  1732. u ) if (( $fl_o != 1 )); then
  1733. echo "$line_no : @CHMOD : Invalid permission string"
  1734. c_error=1
  1735. break
  1736. fi
  1737. fl_o=2
  1738. ;;
  1739. g ) if (( $fl_o != 1 )); then
  1740. echo "$line_no : @CHMOD : Invalid permission string"
  1741. c_error=1
  1742. break
  1743. fi
  1744. fl_o=2
  1745. ;;
  1746. o ) if (( $fl_o != 1 )); then
  1747. echo "$line_no : @CHMOD : Invalid permission string"
  1748. c_error=1
  1749. break
  1750. fi
  1751. fl_o=2
  1752. ;;
  1753. a ) if (( $fl_o != 1 )); then
  1754. echo "$line_no : @CHMOD : Invalid permission string"
  1755. c_error=1
  1756. break
  1757. fi
  1758. fl_o=2
  1759. ;;
  1760. = ) if (( $fl_o != 2 )); then
  1761. echo "$line_no : @CHMOD : Invalid permission string"
  1762. c_error=1
  1763. break
  1764. fi
  1765. fl_o=3
  1766. ;;
  1767. + ) if (( $fl_o != 2 )); then
  1768. echo "$line_no : @CHMOD : Invalid permission string"
  1769. c_error=1
  1770. break
  1771. fi
  1772. fl_o=3
  1773. ;;
  1774. - ) if (( $fl_o != 2 )); then
  1775. echo "$line_no : @CHMOD : Invalid permission string"
  1776. c_error=1
  1777. break
  1778. fi
  1779. fl_o=3
  1780. ;;
  1781. r ) if (( $fl_o < 3 )); then
  1782. echo "$line_no : @CHMOD : Invalid permission string"
  1783. c_error=1
  1784. break
  1785. fi
  1786. fl_o=4
  1787. ;;
  1788. w ) if (( $fl_o < 3 )); then
  1789. echo "$line_no : @CHMOD : Invalid permission string"
  1790. c_error=1
  1791. break
  1792. fi
  1793. fl_o=4
  1794. ;;
  1795. x ) if (( $fl_o < 3 )); then
  1796. echo "$line_no : @CHMOD : Invalid permission string"
  1797. c_error=1
  1798. break
  1799. fi
  1800. fl_o=4
  1801. ;;
  1802. , ) if (( $fl_o < 3 )); then
  1803. echo "$line_no : @CHMOD : Invalid permission string"
  1804. c_error=1
  1805. break
  1806. fi
  1807. fl_o=1
  1808. ;;
  1809. * ) echo "$line_no : @CHMOD : Invalid permission string"
  1810. c_error=1
  1811. break
  1812. ;;
  1813. esac
  1814. done
  1815. fi
  1816. fl_f_list=1
  1817. fl_f_list_type=2
  1818. end_line_no=$(check_end)
  1819. ;;
  1820. "@CHATTR" )
  1821. if (( $fl_no == 1 )); then
  1822. echo "$line_no : !NO cannot be used with @CHATTR"
  1823. c_error=1
  1824. break
  1825. fi
  1826. if (( $fl_o != 0 )); then
  1827. echo "$line_no : @CHATTR : Inside another structure"
  1828. c_error=1
  1829. break
  1830. fi
  1831. fl_o=1
  1832. if (( ${#line[@]} > 6 )); then
  1833. echo "$line_no : @CHATTR : Too many operands"
  1834. c_error=1
  1835. break
  1836. fi
  1837. if (( ${#line[@]} < 2 )); then
  1838. echo "$line_no : @CHATTR : Too few operands"
  1839. c_error=1
  1840. break
  1841. fi
  1842. for (( i=1; i < $[${#line[@]}-1]; i++ )); do
  1843. case ${line[$i]} in
  1844. RECUR ) if (( $fl_chattr_recur == 1 )); then
  1845. echo "$line_no : @CHATTR : RECUR repeated"
  1846. c_error=1
  1847. break
  1848. fi
  1849. fl_chattr_recur=1
  1850. ;;
  1851. VERBOSE ) if (( $fl_chattr_verbose == 1 )); then
  1852. echo "$line_no : @CHATTR : VERBOSE repeated"
  1853. c_error=1
  1854. break
  1855. fi
  1856. fl_chattr_verbose=1
  1857. ;;
  1858. VERSION ) if (( $fl_chattr_version == 1 )); then
  1859. echo "$line_no : @CHATTR : VERSION repeated"
  1860. c_error=1
  1861. break
  1862. fi
  1863. fl_chattr_version=1
  1864. ;;
  1865. * ) if [[ ${line[$i-1]} == "VERSION" ]]; then
  1866. chattr_version_no=${line[$i]}
  1867. fl_chattr_version_c=1
  1868. if ! [[ $chattr_version_no =~ ^[0-9]+$ ]]; then
  1869. echo "$line_no : @CHATTR : Invalid version number"
  1870. c_error=1
  1871. break
  1872. fi
  1873. else
  1874. echo "$line_no : @CHATTR : Invalid operand"
  1875. c_error=1
  1876. break
  1877. fi
  1878. ;;
  1879. esac
  1880. done
  1881. if (( $c_error == 1 )); then break; fi
  1882. if (( $fl_chattr_version == 1 )) && (( $fl_chattr_version_c == 0 )); then
  1883. echo "$line_no : @CHATTR : Missing version number"
  1884. c_error=1
  1885. break
  1886. fi
  1887. for (( i=0; i < ${#line[$[${#line[@]}-1]]}; i++ )); do
  1888. case ${line[$[${#line[@]}-1]]:$i:1} in
  1889. + ) if (( $fl_o != 1 )); then
  1890. echo "$line_no : @CHATTR : Invalid attribute string"
  1891. c_error=1
  1892. break
  1893. fi
  1894. fl_o=2
  1895. ;;
  1896. - ) if (( $fl_o != 1 )); then
  1897. echo "$line_no : @CHATTR : Invalid attribute string"
  1898. c_error=1
  1899. break
  1900. fi
  1901. fl_o=2
  1902. ;;
  1903. = ) if (( $fl_o != 1 )); then
  1904. echo "$line_no : @CHATTR : Invalid attribute string"
  1905. c_error=1
  1906. break
  1907. fi
  1908. fl_o=2
  1909. ;;
  1910. a ) if (( $fl_o != 2 )); then
  1911. echo "$line_no : @CHATTR : Invalid attribute string"
  1912. c_error=1
  1913. break
  1914. fi
  1915. ;;
  1916. c ) if (( $fl_o != 2 )); then
  1917. echo "$line_no : @CHATTR : Invalid attribute string"
  1918. c_error=1
  1919. break
  1920. fi
  1921. ;;
  1922. d ) if (( $fl_o != 2 )); then
  1923. echo "$line_no : @CHATTR : Invalid attribute string"
  1924. c_error=1
  1925. break
  1926. fi
  1927. ;;
  1928. e ) if (( $fl_o != 2 )); then
  1929. echo "$line_no : @CHATTR : Invalid attribute string"
  1930. c_error=1
  1931. break
  1932. fi
  1933. ;;
  1934. i ) if (( $fl_o != 2 )); then
  1935. echo "$line_no : @CHATTR : Invalid attribute string"
  1936. c_error=1
  1937. break
  1938. fi
  1939. ;;
  1940. j ) if (( $fl_o != 2 )); then
  1941. echo "$line_no : @CHATTR : Invalid attribute string"
  1942. c_error=1
  1943. break
  1944. fi
  1945. ;;
  1946. s ) if (( $fl_o != 2 )); then
  1947. echo "$line_no : @CHATTR : Invalid attribute string"
  1948. c_error=1
  1949. break
  1950. fi
  1951. ;;
  1952. t ) if (( $fl_o != 2 )); then
  1953. echo "$line_no : @CHATTR : Invalid attribute string"
  1954. c_error=1
  1955. break
  1956. fi
  1957. ;;
  1958. u ) if (( $fl_o != 2 )); then
  1959. echo "$line_no : @CHATTR : Invalid attribute string"
  1960. c_error=1
  1961. break
  1962. fi
  1963. ;;
  1964. A ) if (( $fl_o != 2 )); then
  1965. echo "$line_no : @CHATTR : Invalid attribute string"
  1966. c_error=1
  1967. break
  1968. fi
  1969. ;;
  1970. D ) if (( $fl_o != 2 )); then
  1971. echo "$line_no : @CHATTR : Invalid attribute string"
  1972. c_error=1
  1973. break
  1974. fi
  1975. ;;
  1976. S ) if (( $fl_o != 2 )); then
  1977. echo "$line_no : @CHATTR : Invalid attribute string"
  1978. c_error=1
  1979. break
  1980. fi
  1981. ;;
  1982. T ) if (( $fl_o != 2 )); then
  1983. echo "$line_no : @CHATTR : Invalid attribute string"
  1984. c_error=1
  1985. break
  1986. fi
  1987. ;;
  1988. * ) echo "$line_no : @CHATTR : Invalid attribute string"
  1989. c_error=1
  1990. break
  1991. ;;
  1992. esac
  1993. done
  1994. fl_f_list=1
  1995. fl_f_list_type=3
  1996. end_line_no=$(check_end)
  1997. ;;
  1998. "@APPEND" ) if (( $fl_no == 1 )); then
  1999. echo "$line_no : !NO cannot be used with @APPEND"
  2000. c_error=1
  2001. break
  2002. fi
  2003. if (( $fl_o != 0 )); then
  2004. echo "$line_no : @APPEND : Inside another structure"
  2005. c_error=1
  2006. break
  2007. fi
  2008. fl_o=1
  2009. if (( ${#line[@]} > 1 )); then
  2010. echo "$line_no : @APPEND : Too many operands"
  2011. c_error=1
  2012. break
  2013. fi
  2014. if (( $[$fl_insert_specified + $fl_replace_specified] != 0 )); then
  2015. echo "$line_no : @APPEND : Cannot be used with @INSERT or @REPLACE"
  2016. c_error=1
  2017. break
  2018. fi
  2019. if (( $fl_append_specified == 1 )); then
  2020. echo "$line_no : @APPEND : Cannot be repeated"
  2021. c_error=1
  2022. break
  2023. fi
  2024. fl_append_specified=1
  2025. fl_start_type=1
  2026. fl_w_list_type=0
  2027. ;;
  2028. "@INSERT" ) if (( $fl_no == 1 )); then
  2029. echo "$line_no : !NO cannot be used with @INSERT"
  2030. c_error=1
  2031. break
  2032. fi
  2033. if (( $fl_o != 0 )) && (( $fl_insert_specified == 0 )); then
  2034. echo "$line_no : @INSERT : Inside another structure"
  2035. c_error=1
  2036. break
  2037. fi
  2038. fl_o=1
  2039. if (( ${#line[@]} > 1 )); then
  2040. echo "$line_no : @INSERT : Too many operands"
  2041. c_error=1
  2042. break
  2043. fi
  2044. if (( $fl_insert_block_completed == 0 )); then
  2045. echo "$line_no : @INSERT : Missing operand in previous statement"
  2046. c_error=1
  2047. break
  2048. fi
  2049. if (( $[$fl_append_specified + $fl_replace_specified] != 0 )); then
  2050. echo "$line_no : @INSERT : Cannot be used with @APPEND or @REPLACE"
  2051. c_error=1
  2052. break
  2053. fi
  2054. fl_insert_block_completed=0
  2055. fl_insert_specified=1
  2056. fl_start_type=2
  2057. fl_w_list_type=1
  2058. fl_insert_line=0
  2059. fl_insert_after=0
  2060. ((fl_insert_index++))
  2061. ((fl_insert_index_after++))
  2062. after_line_no=$(check_after)
  2063. ;;
  2064. "@REPLACE" ) if (( $fl_no == 1 )); then
  2065. echo "$line_no : !NO cannot be used with @REPLACE"
  2066. c_error=1
  2067. break
  2068. fi
  2069. if (( $fl_o != 0 )) && (($fl_replace_specified == 0)); then
  2070. echo "$line_no : @REPLACE : Inside another structure"
  2071. c_error=1
  2072. break
  2073. fi
  2074. fl_o=1
  2075. if (( ${#line[@]} > 1 )); then
  2076. echo "$line_no : @REPLACE : Too many operands"
  2077. c_error=1
  2078. break
  2079. fi
  2080. if (( $fl_replace_block_completed == 0 )); then
  2081. echo "$line_no : @REPLACE : Missing operand in previous statement"
  2082. c_error=1
  2083. break
  2084. fi
  2085. if (( $[$fl_append_specified + $fl_insert_specified] != 0 )); then
  2086. echo "$line_no : @REPLACE : Cannot be used with @APPEND or @INSERT"
  2087. c_error=1
  2088. break
  2089. fi
  2090. fl_replace_block_completed=0
  2091. fl_replace_specified=1
  2092. fl_start_type=3
  2093. fl_w_list_type=2
  2094. fl_replace_with=0
  2095. ((fl_replace_index++))
  2096. ((fl_replace_index_after++))
  2097. with_line_no=$(check_with)
  2098. ;;
  2099. "@COMMAND" ) if (( $fl_no == 1 )); then
  2100. echo "$line_no : !NO cannot be used with @COMMAND"
  2101. c_error=1
  2102. break
  2103. fi
  2104. if (( $fl_o != 0 )); then
  2105. echo "$line_no : @COMMAND : Inside another structure"
  2106. c_error=1
  2107. break
  2108. fi
  2109. fl_o=0
  2110. if (( ${#line[@]} > 1 )); then
  2111. echo "$line_no : @COMMAND t: Too many operands"
  2112. c_error=1
  2113. break
  2114. fi
  2115. fl_w_list_type=3
  2116. fl_command_specified=1
  2117. fl_start_type=4
  2118. end_line_no=$(check_end)
  2119. ;;
  2120. "!NO" ) if ! (( $fl_o == 0 )); then
  2121. echo "$line_no : Missing <END before current line"
  2122. c_error=1 # Error detected
  2123. break
  2124. fi
  2125. if (( $fl_no == 1 )); then
  2126. echo "$line_no : !NO cannot be repeated"
  2127. c_error=1 # Error detected
  2128. break
  2129. fi
  2130. if (( ${#line[@]} > 2 )); then # Syntax checking
  2131. echo "$line_no : !NO - too many arguments"
  2132. c_error=1 # Error detected
  2133. break
  2134. fi
  2135. if (( ${#line[@]} == 2 )); then
  2136. if ! [[ ${line[1]} == "ALL" ]]; then
  2137. echo "$line_no : !NO - only optional operand is ALL"
  2138. c_error=1
  2139. break
  2140. fi
  2141. fi
  2142. fl_no=1 # flag_no=1 indicates '!NO' has been specified once
  2143. # No modification of fl_o, since !NO is optional
  2144. ;;
  2145. "@RESTRICT" ) if (( $fl_o != 0 )) && (( $fl_o != 1 )); then
  2146. # Check if previous operand is either '<END' or '@RESTRICT',
  2147. # since '@RESTRICT' can be specified twice
  2148. echo "$line_no : Missing <END before current line"
  2149. c_error=1 # Error detected
  2150. break
  2151. fi
  2152. fl_o=1 # fl_o=1 indicates '@RESTRICT' has been specified once
  2153. fl_e=0
  2154. fl_f_list_type=0
  2155. fl_restrict_specified=1
  2156. case ${line[1]} in # Analyse 2nd word, after '@RESTRICT'
  2157. USER ) if (( ${#line[@]} == 2 )); then
  2158. echo "$line_no : @RESTRICT : USER specifiy atleast one user"
  2159. c_error=1
  2160. break
  2161. fi
  2162. if (( $fl_r_u == 1 )); then
  2163. echo "$line_no : You can only specify @RESTRICT USER once in each block"
  2164. c_error=1
  2165. break
  2166. fi
  2167. fl_r_u=1
  2168. if (( ${#line[@]} > $[2+${#users[@]}] )); then
  2169. # Even if the user types ALL, it shouldn't exceed the limit
  2170. # This will still be positive if you use ALL, but have an empty users array
  2171. echo "$line_no : @RESTRICT : USER - too many users"
  2172. c_error=1
  2173. break
  2174. fi
  2175. for (( i=2; i < ${#line[@]}; i++ )); do
  2176. if [[ ${line[$i]} == "ALL" ]]; then # Check if 'ALL' or any user are specified at the same time
  2177. fl_all=1
  2178. else
  2179. fl_others=1
  2180. fi
  2181. if (( $fl_all == 1 )) && (( $fl_others == 1 )); then
  2182. echo "$line_no : No other users should be specified with ALL"
  2183. c_error=1 # Error
  2184. break
  2185. fi
  2186. done
  2187. for (( i=0; i < ${#users[@]}; i++ )); do
  2188. fl_u[$i]=0
  2189. fl_u_checked[$i]=0
  2190. done
  2191. if (( $fl_all == 0 )) && (( $fl_others == 1 )); then # Only users, no ALL
  2192. # If ALL is not specified, check specified users
  2193. for (( i=2; i < ${#line[@]}; i++ )); do # Check if users are valid elements of users array
  2194. for (( j=0; j < ${#users[@]}; j++ )); do
  2195. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u_checked[$j]} == 1 )); then
  2196. fl_u_valid_line[$[$i-2]]=1
  2197. fl_u_checked[$j]=1 # Set 1 to indicate user is checked
  2198. #echo "$line_no : ignored user : ${users[$j]}"
  2199. else if [[ ${line[$i]} == ${users[$j]} ]] && (( ${fl_u_checked[$j]} == 1 )); then
  2200. echo "$line_no : user ${users[$j]} is repeated"
  2201. ((c_warn++)) # Warning
  2202. fl_u_valid_line[$[$i-2]]=1
  2203. # Don't set fl_u_checked since it's repeated
  2204. fi
  2205. fi
  2206. done
  2207. done
  2208. for (( i=2; i < ${#line[@]}; i++ )); do # Report invalid users
  2209. if (( ${fl_u_valid_line[$[$i-2]]} == 0 )); then
  2210. echo "$line_no : @RESTRICT USER - user ${line[$i]} is not present in users array"
  2211. c_error=1
  2212. break
  2213. fi
  2214. done
  2215. if (( $c_error == 1)); then break; fi
  2216. fi
  2217. if [[ ${line[2]} == "ALL" ]]; then # If ALL is specified, mark all users
  2218. for (( j=0; j < ${#users[@]}; j++ )); do
  2219. fl_u[$j]=1 # Set 1 to mark user will be selected
  2220. done
  2221. else # If not, then mark individual users
  2222. for (( i=2; i < ${#line[@]}; i++ )); do
  2223. for (( j=0; j < ${#users[@]}; j++ )); do
  2224. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u[$j]} == 1 )); then
  2225. fl_u[$j]=1 # Set 1 to mark user will be selected
  2226. fi
  2227. done
  2228. done
  2229. fi
  2230. ;;
  2231. GROUP ) if (( ${#line[@]} == 2 )); then
  2232. echo "$line_no : @RESTRICT GROUP Specifiy atleast one group"
  2233. c_error=1
  2234. break
  2235. fi
  2236. if (( $fl_r_g == 1 )); then
  2237. echo "$line_no : You can only specify @RESTRICT GROUP once in each block"
  2238. c_error=1 # Error
  2239. break
  2240. fi
  2241. fl_r_g=1
  2242. if (( ${#line[@]} > $[2+${#groups[@]}] )); then
  2243. # Even if ALL is specified, it shouldn't exceed the limit
  2244. # This will still be positive if you use ALL, but have an empty groups array
  2245. echo "$line_no : @RESTRICT GROUP - too many groups"
  2246. c_error=1 # Error
  2247. break
  2248. fi
  2249. for (( i=2; i < ${#line[@]}; i++ )); do
  2250. if [[ ${line[$i]} == "ALL" ]]; then # Check if 'ALL' or any group exist at the same time
  2251. fl_all=1
  2252. else
  2253. fl_others=1
  2254. fi
  2255. if (( $fl_all == 1 )) && (( $fl_others == 1 )); then
  2256. echo "$line_no : No other groups should be specified with ALL"
  2257. c_error=1 # Error
  2258. break
  2259. fi
  2260. done
  2261. for (( i=0; i < ${#groups[@]}; i++ )); do
  2262. fl_g[$i]=0
  2263. fl_g_checked[$i]=0
  2264. done
  2265. if (( $fl_all == 0 )) && (( $fl_others == 1 )); then # Only groups, no ALL
  2266. # If ALL is not specified, check specified groups
  2267. for (( i=2; i < ${#line[@]}; i++ )); do # Check if users are valid elements of users array
  2268. for (( j=0; j < ${#groups[@]}; j++ )); do
  2269. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g_checked[$j]} == 1 )); then
  2270. fl_g_valid_line[$[$i-2]]=1
  2271. fl_g_checked[$j]=1 # Set 1 to indicate user is checked
  2272. #echo "$line_no : ignored user : ${users[$j]}"
  2273. else if [[ ${line[$i]} == ${groups[$j]} ]] && (( ${fl_g_checked[$j]} == 1 )); then
  2274. echo "$line_no : group ${groups[$j]} is repeated"
  2275. ((c_warn++))
  2276. fl_g_valid_line[$[$i-2]]=1
  2277. # Don't set fl_g_checked since it's repeated
  2278. fi
  2279. fi
  2280. done
  2281. done
  2282. for (( i=2; i < ${#line[@]}; i++ )); do # Report invalid users
  2283. if (( ${fl_g_valid_line[$[$i-2]]} == 0 )); then
  2284. echo "$line_no : @RESTRICT GROUP - group ${line[$i]} is not present in groups array"
  2285. c_error=1
  2286. break
  2287. fi
  2288. done
  2289. fi
  2290. if [[ ${line[2]} == "ALL" ]]; then # If ALL is specified, mark all groups
  2291. for (( j=0; j < ${#groups[@]}; j++ )); do
  2292. fl_g[$j]=1 # Set 1 to mark user will be selected
  2293. done
  2294. else # If not, then mark individual groups
  2295. for (( i=2; i < ${#line[@]}; i++ )); do
  2296. for (( j=0; j < ${#groups[@]}; j++ )); do
  2297. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g[$j]} == 1 )); then
  2298. fl_g[$j]=1 # Set 1 to mark user will be selected
  2299. fi
  2300. done
  2301. done
  2302. fi
  2303. ;;
  2304. * ) echo "$line_no : @RESTRICT - missing target"
  2305. c_error=1
  2306. break
  2307. ;;
  2308. esac
  2309. fl_start_type=0
  2310. ;;
  2311. "@EXCLUDE" ) if (( $fl_o == 0 )); then
  2312. echo "$line_no : Missing @RESTRICT before current line"
  2313. c_error=1
  2314. break
  2315. else if (( $fl_o == 2 )); then
  2316. echo "$line_no : +PERM is before @EXCLUDE"
  2317. c_error=1
  2318. break
  2319. fi
  2320. fi # fl_o = 1 is accepted
  2321. case ${line[1]} in
  2322. USER ) if (( ${#line[@]} == 2 )); then
  2323. echo "$line_no : @EXCLUDE USER Specifiy atleast one user"
  2324. c_error=1
  2325. break
  2326. fi
  2327. if (( $fl_e_u == 1 )); then
  2328. echo "$line_no : You can only specify @EXCLUDE USER once in each block"
  2329. c_error=1
  2330. break
  2331. fi
  2332. fl_e_u=1
  2333. for (( i=2; i < ${#line[@]}; i++ )); do
  2334. if [[ ${line[$i]} == "ALL" ]]; then
  2335. echo "$line_no : @EXCLUDE USER ALL is not allowed"
  2336. c_error=1
  2337. break # Break first loop
  2338. fi
  2339. done
  2340. if (( $c_error == 1 )); then break; fi # Break second loop
  2341. if [[ ${#line[@]} > $[2+${#users[@]}] ]]; then
  2342. echo "$line_no : @EXCLUDE USER - too many users"
  2343. c_error=1
  2344. break
  2345. fi
  2346. # Since ALL is not present, check specified users
  2347. for (( i=2; i < ${#line[@]}; i++ )); do # Check if users are valid elements of users array
  2348. for (( j=0; j < ${#users[@]}; j++ )); do
  2349. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u_checked[$j]} == 1 )); then
  2350. fl_u_valid_line[$[$i-2]]=1
  2351. fl_u_checked[$j]=1 # Set 1 to indicate user is checked
  2352. #echo "$line_no : ignored user : ${users[$j]}"
  2353. else if [[ ${line[$i]} == ${users[$j]} ]] && (( ${fl_u_checked[$j]} == 1 )); then
  2354. echo "$line_no : user ${users[$j]} is repeated"
  2355. ((c_warn++))
  2356. fl_u_valid_line[$[$i-2]]=1
  2357. # Don't set fl_u_checked since it's repeated
  2358. fi
  2359. fi
  2360. done
  2361. done
  2362. for (( i=2; i < ${#line[@]}; i++ )); do # Report invalid users
  2363. if (( ${fl_u_valid_line[$[$i-2]]} == 0 )); then
  2364. echo "$line_no : @RESTRICT USER - user ${line[$i]} is not present in users array"
  2365. c_error=1
  2366. break
  2367. fi
  2368. done
  2369. for (( i=2; i < ${#line[@]}; i++ )); do # Mark individual users
  2370. for (( j=0; j < ${#users[@]}; j++ )); do
  2371. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u[$j]} == 0 )); then
  2372. fl_u[$j]=0 # Set 0 to mark user will not be selected
  2373. fi
  2374. done
  2375. done
  2376. for (( i=0; i < ${#users[@]}; i++ )); do
  2377. if (( ${fl_u[$i]} == 1 )); then
  2378. fl_u_check=1
  2379. break
  2380. fi
  2381. done
  2382. if (( $fl_u_check == 0 )); then
  2383. echo "$line_no : Cannot exclude all users previously specified"
  2384. c_error=1
  2385. break
  2386. fi
  2387. ;;
  2388. GROUP ) if (( ${#line[@]} == 2 )); then
  2389. echo "$line_no : @EXCLUDE GROUP Specifiy atleast one group"
  2390. c_error=1
  2391. break
  2392. fi
  2393. if (( $fl_e_g == 1 )); then
  2394. echo "$line_no : You can only specify @EXCLUDE GROUP once in each block"
  2395. c_error=1
  2396. break
  2397. fi
  2398. fl_e_g=1
  2399. for (( i=2; i < ${#line[@]}; i++ )); do
  2400. if [[ ${line[$i]} == "ALL" ]]; then
  2401. echo "$line_no : @EXCLUDE GROUP ALL is not allowed"
  2402. c_error=1
  2403. break # Break first loop
  2404. fi
  2405. done
  2406. if (( $c_error == 1 )); then break; fi # Break second loop
  2407. if [[ ${#line[@]} > $[2+${#groups[@]}] ]]; then
  2408. echo "$line_no : @EXCLUDE GROUP - too many groups"
  2409. c_error=1
  2410. break
  2411. fi
  2412. # Since ALL is not present, check specified groups
  2413. for (( i=2; i < ${#line[@]}; i++ )); do # Check if groups are valid elements of groups array
  2414. for (( j=0; j < ${#groups[@]}; j++ )); do
  2415. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g_checked[$j]} == 1 )); then
  2416. fl_g_valid_line[$[$i-2]]=1
  2417. fl_g_checked[$j]=1 # Set 1 to indicate group is checked
  2418. #echo "$line_no : ignored group : ${groups[$j]}"
  2419. else if [[ ${line[$i]} == ${groups[$j]} ]] && (( ${fl_g_checked[$j]} == 1 )); then
  2420. echo "$line_no : group ${groups[$j]} is repeated"
  2421. ((c_warn++))
  2422. fl_g_valid_line[$[$i-2]]=1
  2423. # Don't set fl_g_checked since it's repeated
  2424. fi
  2425. fi
  2426. done
  2427. done
  2428. for (( i=2; i < ${#line[@]}; i++ )); do # Report invalid users
  2429. if (( ${fl_g_valid_line[$[$i-2]]} == 0 )); then
  2430. echo "$line_no : @RESTRICT GROUP - group flag 1 ${line[$i]} is not present in groups array"
  2431. c_error=1
  2432. break
  2433. fi
  2434. done
  2435. for (( i=2; i < ${#line[@]}; i++ )); do # Mark individual groups
  2436. for (( j=0; j < ${#groups[@]}; j++ )); do
  2437. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g[$j]} == 0 )); then
  2438. fl_g[$j]=0 # Set 0 to mark group will not be selected
  2439. fi
  2440. done
  2441. done
  2442. for (( i=0; i < ${#groups[@]}; i++ )); do
  2443. if (( ${fl_g[$i]} == 1 )); then
  2444. fl_g_check=1
  2445. break
  2446. fi
  2447. done
  2448. if (( $fl_g_check == 0 )); then
  2449. echo "$line_no : Cannot exclude all groups previously specified"
  2450. c_error=1
  2451. break
  2452. fi
  2453. ;;
  2454. * ) echo "$line_no : @EXCLUDE - missing target"; c_error=1; break
  2455. ;;
  2456. esac
  2457. # No modification of fl_o, since @EXCLUDE is optional
  2458. ;;
  2459. "+PERM" ) if (( $fl_no == 0 )); then
  2460. if (( $fl_o == 0 )); then
  2461. echo "$line_no : Missing @RESTRICT before current line"
  2462. c_error=1
  2463. break
  2464. else if (( $fl_perm == 1 )); then
  2465. echo "$line_no : +PERM should not be repeated"
  2466. c_error=1
  2467. break
  2468. fi
  2469. fi # fl_o = 1 is accepted
  2470. fl_o=2
  2471. fl_perm=1
  2472. if (( ${#line[@]} > 2 )); then
  2473. echo "$line_no : +PERM - too many parameters"
  2474. c_error=1
  2475. break
  2476. else if (( ${#line[@]} == 1 )); then
  2477. echo "$line_no : +PERM - missing permission"
  2478. c_error=1
  2479. break
  2480. fi
  2481. fi
  2482. perm_check ${line[1]} fl_perm_check
  2483. if (( $fl_perm_check == 1 )); then
  2484. echo "$line_no : Invalid permission number"
  2485. c_error=1
  2486. break
  2487. else if (( $fl_perm_check == 2 )); then
  2488. echo "$line_no : Invalid permission string"
  2489. c_error=1
  2490. break
  2491. fi
  2492. fi
  2493. fi
  2494. ;;
  2495. "+DPERM" ) if (( $fl_no == 0 )); then
  2496. if (( $fl_o == 0 )); then
  2497. echo "$line_no : Missing @RESTRICT before current line"
  2498. c_error=1
  2499. break
  2500. else if (( $fl_dperm == 1 )); then
  2501. echo "$line_no : +DPERM should not be repeated"
  2502. c_error=1
  2503. break
  2504. fi
  2505. fi # fl_o = 1 is accepted
  2506. fl_o=2
  2507. fl_dperm=1
  2508. if (( ${#line[@]} > 2 )); then
  2509. echo "$line_no : +DPERM - too many parameters"
  2510. c_error=1
  2511. break
  2512. else if (( ${#line[@]} == 1 )); then
  2513. echo "$line_no : +DPERM - missing permission"
  2514. c_error=1
  2515. break
  2516. fi
  2517. fi
  2518. perm_check ${line[1]} fl_perm_check
  2519. if (( $fl_perm_check == 1 )); then
  2520. echo "$line_no : Invalid permission number"
  2521. c_error=1
  2522. break
  2523. else if (( $fl_perm_check == 2 )); then
  2524. echo "$line_no : Invalid permission string"
  2525. c_error=1
  2526. break
  2527. fi
  2528. fi
  2529. fi
  2530. ;;
  2531. "+RECUR" ) if (( $fl_no == 0 )); then
  2532. if (( $fl_o == 0 )); then
  2533. echo "$line_no : Missing @RESTRICT before current line"
  2534. c_error=1
  2535. break
  2536. else if (( $fl_o == 1 )); then
  2537. echo "$line_no : Missing +PERM/+DPERM before current line"
  2538. c_error=1
  2539. break
  2540. fi
  2541. fi
  2542. else if !(( $fl_o == 1 )); then
  2543. echo "$line_no : Missing @RESTRICT before current line"
  2544. c_error=1
  2545. break
  2546. fi
  2547. fi
  2548. if (( ${#line[@]} > 1 )); then # Syntax checking
  2549. echo "$line_no : +RECUR - too many arguments"
  2550. c_error=1 # Error detected
  2551. break
  2552. fi
  2553. fl_recur=1
  2554. ;;
  2555. ">START" )
  2556. if (( $fl_start_type == 0 )); then
  2557. if (( $[$fl_perm + $fl_dperm ] == 0 )) && (( $fl_no == 0 )); then
  2558. echo "$line_no : ACL : Must specify +PERM or +DPERM when !NO is not used"
  2559. c_error=1
  2560. break
  2561. fi
  2562. if (( $fl_no == 0 )); then
  2563. if (( $fl_o == 0 )); then
  2564. echo "$line_no : Missing @RESTRICT before current line"
  2565. c_error=1
  2566. break
  2567. else if (( $fl_o == 1 )); then
  2568. echo "$line_no : Missing +PERM/+DPERM before current line"
  2569. c_error=1
  2570. break
  2571. fi
  2572. fi
  2573. else if !(( $fl_o == 1 )); then
  2574. echo "$line_no : Missing @RESTRICT before current line"
  2575. c_error=1
  2576. break
  2577. fi
  2578. fi
  2579. fl_o=3
  2580. if (( $[$fl_perm + $fl_dperm ] == 0 )) && (( $fl_no == 0 )); then
  2581. echo "$line_no : ACL : Must specify P or D when !NO is not used"
  2582. c_error=1
  2583. break
  2584. fi
  2585. if (( ${#line[@]} > 1 )); then # Syntax checking
  2586. echo "$line_no : >START - too many arguments"
  2587. c_error=1 # Error detected
  2588. break
  2589. fi
  2590. fl_f_list=1
  2591. end_line_no=$(check_end)
  2592. fi
  2593. if (( $fl_start_type == 1 )); then
  2594. if (( ${#line[@]} > 1 )); then # Syntax checking
  2595. echo "$line_no : >START - too many arguments"
  2596. c_error=1 # Error detected
  2597. break
  2598. fi
  2599. end_line_no=$(check_end)
  2600. fl_o=2
  2601. fl_f_list=1
  2602. fl_f_list_type=4
  2603. fi
  2604. if (( $fl_start_type == 2 )); then
  2605. if (( ${#line[@]} > 1 )); then # Syntax checking
  2606. echo "$line_no : >START - too many arguments"
  2607. c_error=1 # Error detected
  2608. break
  2609. fi
  2610. if (( $[$fl_insert_line + $fl_insert_after] == 0 )); then
  2611. echo "$line_no : @INSERT : Please specify @LINE or @AFTER"
  2612. c_error=1
  2613. break
  2614. fi
  2615. end_line_no=$(check_end)
  2616. fl_f_list=1
  2617. fl_f_list_type=5
  2618. fi
  2619. if (( $fl_start_type == 3 )); then
  2620. if (( ${#line[@]} > 1 )); then # Syntax checking
  2621. echo "$line_no : >START - too many arguments"
  2622. c_error=1 # Error detected
  2623. break
  2624. fi
  2625. end_line_no=$(check_end)
  2626. fl_f_list=1
  2627. fl_f_list_type=6
  2628. fi
  2629. if (( $fl_start_type == 4 )); then
  2630. :
  2631. fi
  2632. if (( $fl_start_type == 5 )); then
  2633. if (( $fl_nm_list_ft == 0 )); then
  2634. fl_f_list=1
  2635. fl_f_list_type=7
  2636. else
  2637. fl_nm_list_c=0
  2638. fl_w_list_type=4
  2639. fi
  2640. end_line_no=$(check_end)
  2641. fi
  2642. ;;
  2643. * ) if (( $[$fl_append_specified + $fl_insert_specified + $fl_replace_specified + $fl_command_specified + $fl_nm_list_specified] == 0 )); then
  2644. if (( $fl_restrict_specified == 0 )); then
  2645. echo "$line_no : Missing operand"
  2646. c_error=1
  2647. break
  2648. else
  2649. echo "$line_no : Invalid operand"
  2650. c_error=1
  2651. break
  2652. fi
  2653. fi
  2654. if (( $fl_w_list_type == 0 )); then
  2655. ((append_text_no++))
  2656. fi
  2657. if (( $fl_w_list_type == 1 )); then
  2658. if (( $line_no != $after_line_no )); then
  2659. case ${line[0]} in
  2660. "@LINE" ) if (( $fl_insert_line == 1 )); then
  2661. echo "$line_no : @INSERT : @LINE cannot be repeated"
  2662. c_error=1
  2663. break
  2664. fi
  2665. fl_insert_line=1
  2666. if (( ${#line[@]} > 2 )); then
  2667. echo "$line_no : @INSERT : @LINE too many operands"
  2668. c_error=1
  2669. break
  2670. fi
  2671. if (( ${#line[@]} < 2 )); then
  2672. echo "$line_no : @INSERT : @LINE missing line number"
  2673. c_error=1
  2674. break
  2675. fi
  2676. if ! [[ ${line[1]} =~ ^[0-9]+$ ]]; then # Check if permission number is used
  2677. echo "$line_no : @INSERT : @LINE invalid number"
  2678. c_error=1
  2679. break
  2680. fi
  2681. fl_insert_block_completed=1
  2682. ;;
  2683. * ) if (( $fl_insert_line == 1 )); then
  2684. echo "$line_no : @INSERT : There should be no text after @LINE"
  2685. c_error=1
  2686. break
  2687. fi
  2688. ((insert_text_no++))
  2689. ;;
  2690. esac
  2691. else
  2692. if (( $fl_insert_after == 1 )); then
  2693. echo "$line_no : @INSERT: @AFTER cannot be repeated"
  2694. c_error=1
  2695. break
  2696. fi
  2697. fl_insert_after=1
  2698. if (( ${#line[@]} > 1 )); then
  2699. echo "$line_no : @INSERT : @AFTER too many operands"
  2700. c_error=1
  2701. break
  2702. fi
  2703. fl_insert_block_completed=1
  2704. fi
  2705. if (( $[$fl_insert_line + $fl_insert_after] == 2 )); then
  2706. echo "$line_no : @INSERT : @LINE and @AFTER cannot be used together"
  2707. c_error=1
  2708. break
  2709. fi
  2710. fi
  2711. if (( $fl_w_list_type == 2 )); then
  2712. if (( $line_no != $with_line_no )); then
  2713. if (( $fl_replace_block_completed == 0 )); then
  2714. ((replace_old_text_no++))
  2715. else
  2716. ((replace_new_text_no++))
  2717. fi
  2718. else
  2719. if (( ${#line[@]} > 1 )); then
  2720. echo "$line_no : @WITH too many operands"
  2721. c_error=1
  2722. break
  2723. fi
  2724. if (($fl_replace_block_completed == 1 )); then
  2725. echo "$line_no : @REPLACE : @WITH must be used after @REPLACE"
  2726. c_error=1
  2727. break
  2728. fi
  2729. fl_replace_block_completed=1
  2730. fi
  2731. fi
  2732. if (( $fl_w_list_type == 3 )); then
  2733. if (( $line_no == $end_line_no )); then
  2734. fl_o=0
  2735. fl_f_list=0
  2736. fl_f_list_type=0
  2737. fl_start_type=0
  2738. fl_w_list=0
  2739. fl_w_list_type=0
  2740. ((cmd_no++))
  2741. fi
  2742. ((cmd_line_no++))
  2743. fi
  2744. if (( $fl_w_list_type == 4 )); then
  2745. if (( $line_no != $end_line_no )); then
  2746. if (( fl_nm_list_ug == 0 )); then
  2747. for ((j=0; j<${#line[@]}; j++)); do
  2748. users[$fl_nm_list_c]=${line[$j]}
  2749. ((nm_list_user_no++))
  2750. ((fl_nm_list_c++))
  2751. done
  2752. else
  2753. for ((j=0; j<${#line[@]}; j++)); do
  2754. groups[$fl_nm_list_c]=${line[$j]}
  2755. ((nm_list_group_no++))
  2756. ((fl_nm_list_c++))
  2757. done
  2758. fi
  2759. else
  2760. fl_o=0
  2761. fl_f_list=0
  2762. fl_f_list_type=0
  2763. fl_start_type=0
  2764. fl_w_list=0
  2765. fl_w_list_type=0
  2766. fl_nm_list_c=0
  2767. fl_nm_list_specified=0
  2768. ((nm_list_no++))
  2769. for (( i=0; i < ${#users[@]}; i++ )); do
  2770. fl_u[$i]=0
  2771. done
  2772. for (( i=0; i < ${#groups[@]}; i++ )); do
  2773. fl_g[$i]=0
  2774. done
  2775. fi
  2776. fi
  2777. ;;
  2778. esac
  2779. else
  2780. if (( $fl_f_list_type == 0 )); then
  2781. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  2782. if ! (( $fl_o == 3 )); then
  2783. echo "$line_no : ACL : Missing >START before current line"
  2784. c_error=1
  2785. break
  2786. fi
  2787. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  2788. if (( $[${#line[@]}-$file_name_stitch_c+1] == 2 )); then # too many arguments for permission string/number
  2789. echo "$line_no : ACL : file too little arguments for additional permissions"
  2790. c_error=1
  2791. break
  2792. fi
  2793. if (( $[${#line[@]}-$file_name_stitch_c+1] > 4)); then # too many arguments for permission string/number
  2794. echo "$line_no : ACL : file too many arguments"
  2795. c_error=1
  2796. break
  2797. fi
  2798. if (( $[${#line[@]}-$file_name_stitch_c+1] == 3)); then
  2799. perm_check ${line[$[$file_name_stitch_c]]} fl_perm_check
  2800. if (( fl_perm_check == 1 )); then
  2801. echo "$line_no : ACL : Invalid permission number"
  2802. c_error=1
  2803. break
  2804. else if (( fl_perm_check == 2 )); then
  2805. echo "$line_no : ACL : Invalid permission string"
  2806. c_error=1
  2807. break
  2808. fi
  2809. fi
  2810. if (( ${#line[$[$file_name_stitch_c+1]]} > 3 )); then
  2811. echo "$line_no : ACL : file invalid flags"
  2812. c_error=1
  2813. break
  2814. fi
  2815. for (( i=0; i < ${#line[$[$file_name_stitch_c+1]]}; i++ )); do
  2816. case ${line[$[$file_name_stitch_c+1]]:$i:1} in
  2817. P ) if (( $fl_P == 1 )); then
  2818. echo "$line_no : ACL : file flag P should not be repeated"
  2819. c_error=1
  2820. break
  2821. fi
  2822. if (( $fl_D == 1 )); then
  2823. echo "$line_no : ACL : file flag P should go before flag D"
  2824. c_error=1
  2825. break
  2826. fi
  2827. if (( $fl_R == 1 )); then
  2828. echo "$line_no : ACL : file flag P should go before flag R"
  2829. c_error=1
  2830. break
  2831. fi
  2832. fl_P=1
  2833. ;;
  2834. D ) if (( $fl_D == 1 )); then
  2835. echo "$line_no : ACL : file flag D should not be repeated"
  2836. c_error=1
  2837. break
  2838. fi
  2839. if (( $fl_R == 1 )); then
  2840. echo "$line_no : ACL : file flag D should go before flag R"
  2841. c_error=1
  2842. break
  2843. fi
  2844. fl_D=1
  2845. ;;
  2846. R ) if (( $fl_R == 1 )); then
  2847. echo "$line_no : ACL : file flag R should not be repeated"
  2848. c_error=1
  2849. break
  2850. fi
  2851. fl_R=1
  2852. ;;
  2853. * ) echo "$line_no : ACL : flag invalid flags"
  2854. c_error=1
  2855. break
  2856. ;;
  2857. esac
  2858. done
  2859. else if (( $[${#line[@]}-$file_name_stitch_c+1] == 4)); then
  2860. perm_check ${line[$file_name_stitch_c]} fl_perm_check
  2861. if (( fl_perm_check == 1 )); then
  2862. echo "$line_no : ACL : Invalid permission number"
  2863. c_error=1
  2864. break
  2865. else if (( fl_perm_check == 2 )); then
  2866. echo "$line_no : ACL : Invalid permission string"
  2867. c_error=1
  2868. break
  2869. fi
  2870. fi
  2871. perm_check ${line[$[$file_name_stitch_c+1]]} fl_perm_check
  2872. if (( fl_perm_check == 1 )); then
  2873. echo "$line_no : ACL : Invalid permission number"
  2874. c_error=1
  2875. break
  2876. else if (( fl_perm_check == 2 )); then
  2877. echo "$line_no : ACL : Invalid permission string"
  2878. c_error=1
  2879. break
  2880. fi
  2881. fi
  2882. if (( ${#line[$[$file_name_stitch_c+1]]} > 3 )); then
  2883. echo "$line_no : ACL : file invalid flags"
  2884. c_error=1
  2885. break
  2886. fi
  2887. for (( i=0; i < ${#line[$[$file_name_stitch_c+2]]}; i++ )); do
  2888. case ${line[$[$file_name_stitch_c+2]]:$i:1} in
  2889. P ) if (( $fl_P == 1 )); then
  2890. echo "$line_no : ACL : file flag P should not be repeated"
  2891. c_error=1
  2892. break
  2893. fi
  2894. if (( $fl_D == 1 )); then
  2895. echo "$line_no : ACL : file flag P should go before flag D"
  2896. c_error=1
  2897. break
  2898. fi
  2899. if (( $fl_R == 1 )); then
  2900. echo "$line_no : ACL : file flag P should go before flag R"
  2901. c_error=1
  2902. break
  2903. fi
  2904. fl_P=1
  2905. ;;
  2906. D ) if (( $fl_D == 1 )); then
  2907. echo "$line_no : ACL : file flag D should not be repeated"
  2908. c_error=1
  2909. break
  2910. fi
  2911. if (( $fl_R == 1 )); then
  2912. echo "$line_no : ACL : file flag D should go before flag R"
  2913. c_error=1
  2914. break
  2915. fi
  2916. fl_D=1
  2917. ;;
  2918. R ) if (( $fl_R == 1 )); then
  2919. echo "$line_no : ACL : file flag R should not be repeated"
  2920. c_error=1
  2921. break
  2922. fi
  2923. fl_R=1
  2924. ;;
  2925. * ) echo "$line_no : ACL : flag invalid flags"
  2926. c_error=1
  2927. break
  2928. ;;
  2929. esac
  2930. done
  2931. fi
  2932. fi
  2933. ((file_no++))
  2934. fl_P=0
  2935. fl_D=0
  2936. fl_R=0
  2937. else # If it's the last '<END', then do standard syntax checking for '<END'
  2938. if (( ${#line[@]} > 1 )); then
  2939. echo "$line_no : ACL : Too many operands after <END"
  2940. c_error=1
  2941. break
  2942. fi
  2943. if !(( $fl_o == 3 )); then
  2944. echo "$line_no : ACL : Missing >START before line"
  2945. c_error=1
  2946. break
  2947. fi # fl_o = 3 is accepted
  2948. ((acl_block_no++))
  2949. fl_o=0
  2950. # The following flags are used for the whole block
  2951. fl_r_u=0
  2952. fl_r_g=0
  2953. fl_e_u=0
  2954. fl_e_g=0
  2955. fl_no=0
  2956. fl_f_list=0
  2957. fl_perm=0
  2958. fl_dperm=0
  2959. fl_recur=0
  2960. fl_restrict_specified=0
  2961. fi
  2962. fi
  2963. if (( $fl_f_list_type == 1 )); then
  2964. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  2965. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  2966. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  2967. echo "$line_no : file too many arguments"
  2968. c_error=1
  2969. break
  2970. fi
  2971. ((chown_file_no++))
  2972. else # If it's the last '<END', then do standard syntax checking for '<END'
  2973. if (( ${#line[@]} > 1 )); then
  2974. echo "$line_no : Too many operands after <END"
  2975. c_error=1
  2976. break
  2977. fi
  2978. fl_o=0
  2979. fl_f_list=0
  2980. fl_f_list_type=0
  2981. fl_chown_u_c=0
  2982. fl_chown_g_c=0
  2983. ((chown_no++))
  2984. fi
  2985. fi
  2986. if (( $fl_f_list_type == 2 )); then
  2987. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  2988. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  2989. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  2990. echo "$line_no : file too many arguments"
  2991. c_error=1
  2992. break
  2993. fi
  2994. ((chmod_file_no++))
  2995. else # If it's the last '<END', then do standard syntax checking for '<END'
  2996. if (( ${#line[@]} > 1 )); then
  2997. echo "$line_no : Too many operands after <END"
  2998. c_error=1
  2999. break
  3000. fi
  3001. fl_o=0
  3002. fl_f_list=0
  3003. fl_f_list_type=0
  3004. ((chmod_no++))
  3005. fi
  3006. fi
  3007. if (( $fl_f_list_type == 3 )); then
  3008. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3009. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  3010. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  3011. echo "$line_no : file too many arguments"
  3012. c_error=1
  3013. break
  3014. fi
  3015. ((chattr_file_no++))
  3016. else # If it's the last '<END', then do standard syntax checking for '<END'
  3017. if (( ${#line[@]} > 1 )); then
  3018. echo "$line_no : Too many operands after <END"
  3019. c_error=1
  3020. break
  3021. fi
  3022. fl_o=0
  3023. fl_f_list=0
  3024. fl_f_list_type=0
  3025. fl_chattr_recur=0
  3026. fl_chattr_verbose=0
  3027. fl_chattr_version=0
  3028. fl_chattr_version_c=0
  3029. chattr_version_no=0
  3030. chattr_string=""
  3031. chattr_arg_string=""
  3032. ((chattr_no++))
  3033. fi
  3034. fi
  3035. if (( $fl_f_list_type == 4 )); then
  3036. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3037. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  3038. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  3039. echo "$line_no : file too many arguments"
  3040. c_error=1
  3041. break
  3042. fi
  3043. ((append_file_no++))
  3044. else # If it's the last '<END', then do standard syntax checking for '<END'
  3045. if (( ${#line[@]} > 1 )); then
  3046. echo "$line_no : Too many operands after <END"
  3047. c_error=1
  3048. break
  3049. fi
  3050. fl_o=0
  3051. fl_f_list=0
  3052. fl_f_list_type=0
  3053. fl_start_type=0
  3054. fl_w_list=0
  3055. fl_w_list_type=0
  3056. fl_append_specified=0
  3057. ((append_no++))
  3058. fi
  3059. fi
  3060. if (( $fl_f_list_type == 5 )); then
  3061. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3062. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  3063. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  3064. echo "$line_no : file too many arguments"
  3065. c_error=1
  3066. break
  3067. fi
  3068. ((insert_file_no++))
  3069. else # If it's the last '<END', then do standard syntax checking for '<END'
  3070. if (( ${#line[@]} > 1 )); then
  3071. echo "$line_no : Too many operands after <END"
  3072. c_error=1
  3073. break
  3074. fi
  3075. fl_o=0
  3076. fl_f_list=0
  3077. fl_f_list_type=0
  3078. fl_start_type=0
  3079. fl_w_list=0
  3080. fl_w_list_type=0
  3081. fl_insert_specified=0
  3082. fl_insert_line=0
  3083. fl_insert_after=0
  3084. ((insert_no++))
  3085. fi
  3086. fi
  3087. if (( $fl_f_list_type == 6 )); then
  3088. if (( $line_no != $end_line_no )); then # If it's not the last '<END', process it as file name
  3089. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  3090. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then # too many arguments for permission string/number
  3091. echo "$line_no : file too many arguments"
  3092. c_error=1
  3093. break
  3094. fi
  3095. ((replace_file_no++))
  3096. else # If it's the last '<END', then do standard syntax checking for '<END'
  3097. if (( ${#line[@]} > 1 )); then
  3098. echo "$line_no : Too many operands after <END"
  3099. c_error=1
  3100. break
  3101. fi
  3102. fl_o=0
  3103. fl_f_list=0
  3104. fl_f_list_type=0
  3105. fl_start_type=0
  3106. fl_w_list=0
  3107. fl_w_list_type=0
  3108. fl_replace_specified=0
  3109. ((replace_no++))
  3110. fi
  3111. fi
  3112. if (( $fl_f_list_type == 7 )); then
  3113. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3114. filename_stitch line[@] file_name_stitch_string file_name_stitch_c c_error
  3115. if (( $[${#line[@]}-$file_name_stitch_c+1] > 1)); then
  3116. echo "$line_no : file too many arguments"
  3117. c_error=1
  3118. break
  3119. fi
  3120. if [ ! -f "$(char_deescape_echo file_name_stitch_string)" ]; then
  3121. echo "$line_no : @NAME_LIST : File does not exist"
  3122. exit
  3123. fi
  3124. while read -r nm_list_line_raw; do
  3125. if [[ ($nm_list_line_raw =~ ^$ || -z $nm_list_line_raw || $nm_list_line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  3126. ((nm_list_file_line_no++))
  3127. continue # If so, ignore line, check next line, still add line number though
  3128. fi
  3129. char_escape nm_list_line_raw
  3130. for nm_list_word in $nm_list_line_raw; do # Validate each word in line
  3131. if [[ $nm_list_word == \#* || $nm_list_word == '#' ]]; then # Ignore comments
  3132. # If word starts with '#', stop reading (probably is a comment)
  3133. break
  3134. fi
  3135. if (( fl_nm_list_ug == 0 )); then
  3136. users[$fl_nm_list_c]=$nm_list_word
  3137. ((nm_list_user_no++))
  3138. else
  3139. groups[$fl_nm_list_c]=$nm_list_word
  3140. ((nm_list_group_no++))
  3141. fi
  3142. ((fl_nm_list_c++))
  3143. done
  3144. ((nm_list_file_line_no++))
  3145. ((nm_list_file_a_line_no++))
  3146. done < "$(char_deescape_echo file_name_stitch_string)"
  3147. ((nm_list_file_no++))
  3148. else # If it's the last '<END', then do standard syntax checking for '<END'
  3149. if (( ${#line[@]} > 1 )); then
  3150. echo "$line_no : Too many operands after <END"
  3151. c_error=1
  3152. break
  3153. fi
  3154. fl_o=0
  3155. fl_f_list=0
  3156. fl_f_list_type=0
  3157. fl_start_type=0
  3158. fl_w_list=0
  3159. fl_w_list_type=0
  3160. fl_nm_list_c=0
  3161. fl_nm_list_specified=0
  3162. ((nm_list_no++))
  3163. fi
  3164. fi
  3165. fi
  3166. if (( $c_error == 1)); then break; fi
  3167. ((line_no++))
  3168. ((a_line_no++))
  3169. unset line
  3170. done < "$filelist"
  3171. fl_l=0
  3172. #echo "USERS"
  3173. #for ((i=0; i < ${#users[@]}; i++)); do
  3174. # echo "${users[$i]}"
  3175. #done
  3176. #for ((i=0; i < ${#groups[@]}; i++)); do
  3177. # echo "${groups[$i]}"
  3178. #done
  3179. if (( $c_error == 1 )); then
  3180. exit
  3181. fi
  3182. if (( $fl_o != 0 )); then
  3183. echo "$line_no : Incomplete entry"
  3184. exit
  3185. fi
  3186. if (( $fl_I_d == 1 )); then
  3187. if (( $fl_I_g == 0 )); then
  3188. echo ""
  3189. fi
  3190. echo "# Time : $(date +%H\:%M\ %d/%m/%Y)"
  3191. fi
  3192. if (( $fl_I_s == 1 )); then
  3193. if (( $fl_I_g == 1 )); then
  3194. echo "#"
  3195. else
  3196. echo ""
  3197. fi
  3198. echo "# Statistics"
  3199. echo "#"
  3200. echo "# General:"
  3201. echo "# Lines in file : $[$line_no-1]"
  3202. echo "# Lines of rules : $[$a_line_no-1]"
  3203. echo "# Warnings : $c_warn"
  3204. echo "#"
  3205. echo "# name list:"
  3206. echo "# Blocks : $nm_list_no"
  3207. echo "# Files : $nm_list_file_no"
  3208. echo "# File lines read : $nm_list_file_line_no"
  3209. echo "# File lines processed : $nm_list_file_a_line_no"
  3210. echo "# Users : $nm_list_user_no"
  3211. echo "# Groups : $nm_list_group_no"
  3212. echo "#"
  3213. echo "# setfacl:"
  3214. echo "# ACL blocks : $acl_block_no"
  3215. echo "# STRAY entries : $stray_no"
  3216. echo "# Number of files or directories : $file_no"
  3217. echo "#"
  3218. echo "# chown:"
  3219. echo "# Blocks : $chown_no"
  3220. echo "# Number of files or directories : $chown_file_no"
  3221. echo "#"
  3222. echo "# chmod:"
  3223. echo "# Blocks : $chmod_no"
  3224. echo "# Number of files or directories : $chmod_file_no"
  3225. echo "#"
  3226. echo "# chattr:"
  3227. echo "# Blocks : $chattr_no"
  3228. echo "# Number of files or directories : $chattr_file_no"
  3229. echo "#"
  3230. echo "# append:"
  3231. echo "# Blocks : $append_no"
  3232. echo "# Lines of text : $append_text_no"
  3233. echo "# Number of files : $append_file_no"
  3234. echo "#"
  3235. echo "# insert:"
  3236. echo "# Blocks : $insert_no"
  3237. echo "# Lines of text : $insert_text_no"
  3238. echo "# Number of files : $insert_file_no"
  3239. echo "#"
  3240. echo "# replace:"
  3241. echo "# Blocks : $replace_no"
  3242. echo "# Lines of Old text : $replace_old_text_no"
  3243. echo "# Lines of New text : $replace_new_text_no"
  3244. echo "# Number of files : $replace_file_no"
  3245. echo "#"
  3246. echo "# command:"
  3247. echo "# Blocks : $cmd_no"
  3248. echo "# Lines : $cmd_line_no"
  3249. fi
  3250. if (( $fl_I_t == 1 )); then
  3251. echo "No error detected"
  3252. exit
  3253. fi
  3254. for (( i=0; i < ${#users[@]}; i++ )); do
  3255. fl_u[$i]=0
  3256. done
  3257. for (( i=0; i < ${#groups[@]}; i++ )); do
  3258. fl_g[$i]=0
  3259. done
  3260. fl_i=1
  3261. fl_insert_index=0
  3262. fl_replace_index=0
  3263. line_no=1
  3264. while read -r line_raw; do
  3265. if [[ ($line_raw =~ ^$ || -z $line_raw || $line_raw =~ ^# ) ]]; then # Check if line is empty/null/spaces or starts with '#'
  3266. continue # If so, ignore line, check next line, still add line number though
  3267. fi
  3268. for (( i=0; i < ${#users[@]}; i++ )); do # Initialise 'users' array
  3269. fl_u_valid_line[$i]=0
  3270. fl_u_checked[$i]=0
  3271. done
  3272. for (( i=0; i < ${#groups[@]}; i++ )); do # Initialise 'groups' array
  3273. fl_g_valid_line[$i]=0
  3274. fl_g_checked[$i]=0
  3275. done
  3276. char_escape_quiet line_raw
  3277. i=0
  3278. line=() # Initialise primary line buffer
  3279. for word in $line_raw; do # Validate each word in line
  3280. if [[ $word == \#* || $word == '#' ]]; then # Ignore comments
  3281. # If word starts with '#', stop reading (probably is a comment)
  3282. break
  3283. fi
  3284. line[$i]="$word" # Push words to line[]
  3285. ((i++))
  3286. done
  3287. if (( $fl_f_list == 0 )); then
  3288. case ${line[0]} in
  3289. "@NAME_LIST" )
  3290. fl_o=0
  3291. fl_start_type=4
  3292. fl_nm_list_specified=1
  3293. ;;
  3294. "@STRAY" )
  3295. for (( i=1; i < ${#line[@]}; i++ )); do
  3296. case ${line[$i]} in
  3297. "NO" ) fl_no=1
  3298. ;;
  3299. RES )
  3300. ;;
  3301. USR )
  3302. ;;
  3303. GRP )
  3304. ;;
  3305. P ) fl_P=1
  3306. ;;
  3307. D ) fl_D=1
  3308. ;;
  3309. R ) fl_R=1
  3310. ;;
  3311. * ) if [[ ${line[$i-1]} == "USR" ]]; then
  3312. for (( j=0; j < ${#users[@]}; j++ )); do
  3313. if [[ ${line[$i]} == ${users[$j]} ]]; then
  3314. fl_u[$j]=1
  3315. break
  3316. fi
  3317. done
  3318. fi
  3319. if [[ ${line[$i-1]} == "GRP" ]]; then
  3320. for (( j=0; j < ${#groups[@]}; j++ )); do
  3321. if [[ ${line[$i]} == ${groups[$j]} ]]; then
  3322. fl_g[$j]=1
  3323. break
  3324. fi
  3325. done
  3326. fi
  3327. if [[ ${line[$i-1]} == "P" ]]; then
  3328. fl_stray_P_str=$i
  3329. fi
  3330. if [[ ${line[$i-1]} == "D" ]]; then
  3331. fl_stray_D_str=$i
  3332. fi
  3333. ;;
  3334. esac
  3335. done
  3336. if (( $fl_no == 1 )); then
  3337. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no s_aperm line[$[${#line[@]}-1]] temp fl_R fl_NOALL fl_apply fl_gen
  3338. fi
  3339. if (( $fl_P == 1 )) && (( $fl_no == 0 )); then
  3340. temp=0
  3341. s_aperm=${line[$fl_stray_P_str]}
  3342. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no s_aperm line[$[${#line[@]}-1]] temp fl_R fl_NOALL fl_apply fl_gen
  3343. fi
  3344. if (( $fl_D == 1 )) && (( $fl_no == 0 )); then
  3345. s_aperm=${line[$fl_stray_D_str]}
  3346. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no s_aperm line[$[${#line[@]}-1]] fl_D fl_R fl_NOALL fl_apply fl_gen
  3347. fi
  3348. fl_P=0
  3349. fl_D=0
  3350. fl_R=0
  3351. fl_no=0
  3352. for (( i=0; i < ${#users[@]}; i++ )); do
  3353. fl_u[$i]=0
  3354. done
  3355. for (( i=0; i < ${#groups[@]}; i++ )); do
  3356. fl_g[$i]=0
  3357. done
  3358. ;;
  3359. "@CHOWN" )
  3360. fl_o=0
  3361. for (( i=1; i < ${#line[@]}; i++ )); do
  3362. case ${line[$i]} in
  3363. USER ) fl_o=1
  3364. fl_chown_u_specified=1
  3365. ;;
  3366. GROUP ) fl_o=1
  3367. fl_chown_g_specified=1
  3368. ;;
  3369. * ) if [[ ${line[$i-1]} == "USER" ]]; then
  3370. fl_chown_u=${line[$i]}
  3371. fi
  3372. if [[ ${line[$i-1]} == "GROUP" ]]; then
  3373. fl_chown_g=${line[$i]}
  3374. fi
  3375. ;;
  3376. esac
  3377. done
  3378. fl_f_list=1
  3379. fl_f_list_type=1
  3380. end_line_no=$(check_end)
  3381. ;;
  3382. "@CHMOD" ) fl_o=0
  3383. chmod_perm_string=${line[1]}
  3384. fl_f_list=1
  3385. fl_f_list_type=2
  3386. end_line_no=$(check_end)
  3387. ;;
  3388. "@CHATTR" )fl_o=0
  3389. for (( i=1; i < $[${#line[@]}-1]; i++ )); do
  3390. case ${line[$i]} in
  3391. RECUR ) fl_chattr_recur=1
  3392. ;;
  3393. VERBOSE ) fl_chattr_verbose=1
  3394. ;;
  3395. VERSION ) fl_chattr_version=1
  3396. ;;
  3397. * ) if [[ ${line[$i-1]} == "VERSION" ]]; then
  3398. chattr_version_no=${line[$i]}
  3399. fi
  3400. ;;
  3401. esac
  3402. done
  3403. chattr_string=${line[$[${#line[@]}-1]]}
  3404. if (( ($fl_chattr_recur + $fl_chattr_verbose + $fl_chattr_version) != 0 )); then
  3405. chattr_arg_string+="-"
  3406. fi
  3407. if (( $fl_chattr_recur == 1 )); then
  3408. chattr_arg_string+="R"
  3409. fi
  3410. if (( $fl_chattr_verbose == 1 )); then
  3411. chattr_arg_string+="V"
  3412. fi
  3413. if (( ($fl_chattr_recur + $fl_chattr_verbose) != 0 )); then
  3414. chattr_arg_string+=' '
  3415. fi
  3416. if (( $fl_chattr_version == 1 )); then
  3417. chattr_arg_string+="-v $chattr_version_no "
  3418. fi
  3419. fl_f_list=1
  3420. fl_f_list_type=3
  3421. end_line_no=$(check_end)
  3422. ;;
  3423. "@APPEND" ) fl_o=0
  3424. fl_append_specified=1
  3425. fl_start_type=1
  3426. fl_w_list_type=0
  3427. ;;
  3428. "@INSERT" ) fl_o=0
  3429. fl_insert_specified=1
  3430. fl_start_type=2
  3431. fl_w_list_type=1
  3432. fl_insert_line=0
  3433. fl_insert_after=0
  3434. ((fl_insert_index++))
  3435. insert_string_buffer_after=""
  3436. insert_string_buffer=""
  3437. sed_mul_line_string=""
  3438. fl_insert_string_after_first=1
  3439. fl_insert_string_first=1
  3440. after_line_no=$(check_after)
  3441. ;;
  3442. "@REPLACE" ) fl_o=0
  3443. fl_replace_specified=1
  3444. fl_start_type=3
  3445. fl_w_list_type=2
  3446. fl_replace_with=0
  3447. ((fl_replace_index++))
  3448. replace_string_buffer_with=""
  3449. replace_string_buffer=""
  3450. sed_mul_line_string=""
  3451. fl_replace_string_with_first=1
  3452. fl_replace_string_first=1
  3453. with_line_no=$(check_with)
  3454. ;;
  3455. "@COMMAND" ) fl=0
  3456. fl_w_list_type=3
  3457. fl_start_type=4
  3458. end_line_no=$(check_end)
  3459. ;;
  3460. "!NO" ) fl_no=1 # action by default is 'm', if !NO is specified, action changes to 'x'
  3461. if (( ${#line[@]} == 2 )); then
  3462. fl_NOALL=1
  3463. fi
  3464. ;;
  3465. "@RESTRICT" ) case ${line[1]} in
  3466. USER ) if [[ ${line[2]} == "ALL" ]]; then # If ALL is specified, mark all users
  3467. for (( j=0; j < ${#users[@]}; j++ )); do
  3468. fl_u[$j]=1 # Set 1 to mark user will be selected
  3469. done
  3470. else # If not, then mark individual users
  3471. for (( i=2; i < ${#line[@]}; i++ )); do
  3472. for (( j=0; j < ${#users[@]}; j++ )); do
  3473. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u[$j]} == 1 )); then
  3474. fl_u[$j]=1 # Set 1 to mark user will be selected
  3475. fi
  3476. done
  3477. done
  3478. fi
  3479. ;;
  3480. GROUP ) if [[ ${line[2]} == "ALL" ]]; then # If ALL is specified, mark all groups
  3481. for (( j=0; j < ${#groups[@]}; j++ )); do
  3482. fl_g[$j]=1 # Set 1 to mark user will be selected
  3483. done
  3484. else # If not, then mark individual groups
  3485. for (( i=2; i < ${#line[@]}; i++ )); do
  3486. for (( j=0; j < ${#groups[@]}; j++ )); do
  3487. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g[$j]} == 1 )); then
  3488. fl_g[$j]=1 # Set 1 to mark user will be selected
  3489. fi
  3490. done
  3491. done
  3492. fi
  3493. ;;
  3494. esac
  3495. fl_start_type=0
  3496. ;;
  3497. "@EXCLUDE" ) case ${line[1]} in
  3498. USER ) for (( i=2; i < ${#line[@]}; i++ )); do # Mark individual users
  3499. for (( j=0; j < ${#users[@]}; j++ )); do
  3500. if [[ ${line[$i]} == ${users[$j]} ]] && !(( ${fl_u[$j]} == 0 )); then
  3501. fl_u[$j]=0 # Set 0 to mark user will not be selected
  3502. fi
  3503. done
  3504. done
  3505. ;;
  3506. GROUP ) for (( i=2; i < ${#line[@]}; i++ )); do # Mark individual groups
  3507. for (( j=0; j < ${#groups[@]}; j++ )); do
  3508. if [[ ${line[$i]} == ${groups[$j]} ]] && !(( ${fl_g[$j]} == 0 )); then
  3509. fl_g[$j]=0 # Set 0 to mark group will not be selected
  3510. fi
  3511. done
  3512. done
  3513. ;;
  3514. esac
  3515. ;;
  3516. "+PERM" ) d_perm=${line[1]} # Default permission of current ACL block, can be number or string
  3517. fl_perm=1
  3518. ;;
  3519. "+DPERM" ) d_dperm=${line[1]}
  3520. fl_dperm=1
  3521. ;;
  3522. "+RECUR" ) fl_R=1
  3523. ;;
  3524. ">START" ) if (( $fl_start_type == 0 )); then
  3525. fl_o=3
  3526. fl_f_list=1
  3527. end_line_no=$(check_end)
  3528. fi
  3529. if (( $fl_start_type == 1 )); then
  3530. fl_f_list=1
  3531. fl_f_list_type=4
  3532. end_line_no=$(check_end)
  3533. fi
  3534. if (( $fl_start_type == 2 )); then
  3535. fl_f_list=1
  3536. fl_f_list_type=5
  3537. end_line_no=$(check_end)
  3538. fi
  3539. if (( $fl_start_type == 3 )); then
  3540. fl_f_list=1
  3541. fl_f_list_type=6
  3542. end_line_no=$(check_end)
  3543. fi
  3544. if (( $fl_start_type == 4 )); then
  3545. if (( $fl_nm_list_ft == 0 )); then
  3546. fl_f_list=1
  3547. fl_f_list_type=7
  3548. else
  3549. fl_nm_list_c=0
  3550. fl_w_list_type=4
  3551. fi
  3552. end_line_no=$(check_end)
  3553. fi
  3554. ;;
  3555. * ) if (( $fl_w_list_type == 0 )); then
  3556. if (( $fl_append_string_first == 1 )); then
  3557. append_string_buffer+="$line_raw"
  3558. fl_append_string_first=0
  3559. else
  3560. append_string_buffer+="\n$line_raw"
  3561. fi
  3562. fi
  3563. if (( $fl_w_list_type == 1 )); then
  3564. if (( $line_no != $after_line_no )); then
  3565. case ${line[0]} in
  3566. "@LINE" ) fl_insert_line=1
  3567. insert_line_or_after[$fl_insert_index]=1
  3568. insert_line_number_array[$fl_insert_index]=${line[1]}
  3569. ;;
  3570. * ) if (( $fl_insert_after == 1 )); then
  3571. if (( $fl_insert_string_after_first == 1 )); then
  3572. insert_string_buffer_after+="$line_raw"
  3573. insert_string_buffer_after_array[$fl_insert_index]=$insert_string_buffer_after
  3574. fl_insert_string_after_first=0
  3575. else
  3576. insert_string_buffer_after+="\n$line_raw"
  3577. insert_string_buffer_after_array[$fl_insert_index]=$insert_string_buffer_after
  3578. sed_mul_line_string+="N;"
  3579. insert_sed_mul_line_string_array[$fl_insert_index]=$sed_mul_line_string
  3580. fi
  3581. else
  3582. if (( $fl_insert_string_first == 1 )); then
  3583. insert_string_buffer+="$line_raw"
  3584. insert_string_buffer_array[$fl_insert_index]=$insert_string_buffer
  3585. fl_insert_string_first=0
  3586. else
  3587. insert_string_buffer+="\n$line_raw"
  3588. insert_string_buffer_array[$fl_insert_index]=$insert_string_buffer
  3589. fi
  3590. fi
  3591. ;;
  3592. esac
  3593. else
  3594. fl_insert_after=1
  3595. insert_line_or_after[$fl_insert_index]=0
  3596. fi
  3597. fi
  3598. if (( $fl_w_list_type == 2 )); then
  3599. if (( $line_no != $with_line_no )); then
  3600. if (( $fl_replace_with == 1 )); then
  3601. if (( $fl_replace_string_with_first == 1 )); then
  3602. replace_string_buffer_with+="$line_raw"
  3603. replace_string_buffer_with_array[$fl_replace_index]=$replace_string_buffer_with
  3604. fl_replace_string_with_first=0
  3605. else
  3606. replace_string_buffer_with+="\n$line_raw"
  3607. replace_string_buffer_with_array[$fl_replace_index]=$replace_string_buffer_with
  3608. replace_sed_mul_line_string_array[$fl_replace_index]=$sed_mul_line_string
  3609. fi
  3610. else
  3611. if (( $fl_replace_string_first == 1 )); then
  3612. replace_string_buffer+="$line_raw"
  3613. replace_string_buffer_array[$fl_replace_index]=$replace_string_buffer
  3614. fl_replace_string_first=0
  3615. else
  3616. replace_string_buffer+="\n$line_raw"
  3617. replace_string_buffer_array[$fl_replace_index]=$replace_string_buffer
  3618. replace_sed_mul_line_string_array[$fl_replace_index]=$sed_mul_line_string
  3619. replace_mul_line=1
  3620. fi
  3621. fi
  3622. else
  3623. if (( $fl_replace_with == 1 )); then
  3624. if (( $fl_replace_string_with_first == 1 )); then
  3625. replace_string_buffer_with+="$line_raw"
  3626. replace_string_buffer_with_array[$fl_replace_index]=$replace_string_buffer_with
  3627. fl_replace_string_with_first=0
  3628. else
  3629. replace_string_buffer_with+="\n$line_raw"
  3630. replace_string_buffer_with_array[$fl_replace_index]=$replace_string_buffer_after
  3631. replace_sed_mul_line_string_array[$fl_replace_index]=$sed_mul_line_string
  3632. fi
  3633. else
  3634. fl_replace_with=1
  3635. fi
  3636. fi
  3637. fi
  3638. if (( $fl_w_list_type == 3 )); then
  3639. if (( $line_no != $end_line_no )); then
  3640. if (( $fl_I_a == 1 )); then
  3641. $line_raw
  3642. fi
  3643. if (( $fl_I_g == 1 )); then
  3644. echo "$line_raw"
  3645. fi
  3646. else
  3647. fl_o=0
  3648. fl_f_list=0
  3649. fl_f_list_type=0
  3650. fl_start_type=0
  3651. fl_w_list=0
  3652. fl_w_list_type=0
  3653. fi
  3654. fi
  3655. if (( $fl_w_list_type == 4 )); then
  3656. if (( $line_no != $end_line_no)); then
  3657. if (( fl_nm_list_ug == 0 )); then
  3658. for ((j=0; j<${#line[@]}; j++)); do
  3659. users[$fl_nm_list_c]=${line[$j]}
  3660. ((nm_list_user_no++))
  3661. ((fl_nm_list_c++))
  3662. done
  3663. else
  3664. for ((j=0; j<${#line[@]}; j++)); do
  3665. groups[$fl_nm_list_c]=${line[$j]}
  3666. ((nm_list_group_no++))
  3667. ((fl_nm_list_c++))
  3668. done
  3669. fi
  3670. else
  3671. fl_o=0
  3672. fl_f_list=0
  3673. fl_f_list_type=0
  3674. fl_start_type=0
  3675. fl_w_list=0
  3676. fl_w_list_type=0
  3677. fl_nm_list_c=0
  3678. fl_nm_list_specified=0
  3679. ((nm_list_no++))
  3680. for (( i=0; i < ${#users[@]}; i++ )); do
  3681. fl_u[$i]=0
  3682. done
  3683. for (( i=0; i < ${#groups[@]}; i++ )); do
  3684. fl_g[$i]=0
  3685. done
  3686. fi
  3687. fi
  3688. ;;
  3689. esac
  3690. else
  3691. if (( $fl_f_list_type == 0 )); then
  3692. if [[ $line_no != $end_line_no ]]; then
  3693. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3694. if (( $[${#line[@]}-$file_name_stitch_c+1] == 1 )); then # No individual permission specified, follow default permission
  3695. if (( $fl_no == 1 )); then
  3696. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no a_perm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3697. fi
  3698. if (( $fl_perm == 1 )) && (( $fl_no == 0 )); then
  3699. fl_D=0
  3700. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no d_perm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3701. fi
  3702. if (( $fl_dperm == 1 )) && (( $fl_no == 0 )); then
  3703. fl_D=1
  3704. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no d_dperm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3705. fi
  3706. fl_D=0
  3707. else if (( $[${#line[@]}-$file_name_stitch_c+1] == 3 )); then
  3708. for (( i=0; i < ${#line[$[$file_name_stitch_c+1]]}; i++ )); do
  3709. case ${line[$[$file_name_stitch_c+1]]:$i:1} in
  3710. P ) fl_P=1
  3711. ;;
  3712. D ) fl_D=1
  3713. ;;
  3714. R ) fl_R=1
  3715. ;;
  3716. esac
  3717. done
  3718. if (( $fl_P == 1 )); then
  3719. a_perm=${line[$file_name_stitch_c]}
  3720. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no a_perm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3721. fi
  3722. if (( $fl_D == 1 )); then
  3723. a_dperm=${line[$file_name_stitch_c]}
  3724. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no a_dperm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3725. fi
  3726. else # ${#line[@]} == 4
  3727. a_perm=${line[$file_name_stitch_c]}
  3728. a_dperm=${line[$file_name_stitch_c]}
  3729. for (( i=0; i < ${#line[$[$file_name_stitch_c+2]]}; i++ )); do
  3730. if [[ ${line[3]:$i:1} == 'R' ]]; then
  3731. fl_R=1
  3732. break
  3733. fi
  3734. done
  3735. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no a_perm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3736. fl_D=1
  3737. perm_set users[@] groups[@] fl_u[@] fl_g[@] fl_no a_dperm file_name_stitch_string fl_D fl_R fl_NOALL fl_apply fl_gen
  3738. fl_D=0
  3739. fi
  3740. fi
  3741. fl_P=0
  3742. fl_D=0
  3743. fl_R=0
  3744. else
  3745. for (( i=0; i < ${#users[@]}; i++ )); do
  3746. fl_u[$i]=0
  3747. done
  3748. for (( i=0; i < ${#groups[@]}; i++ )); do
  3749. fl_g[$i]=0
  3750. done
  3751. unset d_perm
  3752. fi
  3753. # Reset flags
  3754. # The following flags are used for the whole block
  3755. fl_no_b=$fl_no
  3756. fl_no=0
  3757. fl_NOALL=0
  3758. fl_f_list=0
  3759. fl_e=1
  3760. fl_recur=0
  3761. fi
  3762. if (( $fl_f_list_type == 1 )); then
  3763. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3764. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3765. if (( $fl_I_a == 1 )); then
  3766. if (( $fl_chown_u_specified == 0 )); then
  3767. chown :$fl_chown_g $(char_deescape_echo file_name_stitch_string)
  3768. else
  3769. if (( $fl_chown_g_specified == 0 )); then
  3770. chown $fl_chown_u $(char_deescape_echo file_name_stitch_string)
  3771. else
  3772. chown $fl_chown_u:$fl_chown_g $(char_deescape_echo file_name_stitch_string)
  3773. fi
  3774. fi
  3775. fi
  3776. if (( $fl_I_g == 1 )); then
  3777. if (( $fl_chown_u_specified == 0 )); then
  3778. echo "chown :$fl_chown_g $(char_deescape $file_name_stitch_string)"
  3779. else
  3780. if (( $fl_chown_g_specified == 0 )); then
  3781. echo "chown $fl_chown_u $(char_deescape_echo file_name_stitch_string)"
  3782. else
  3783. echo "chown $fl_chown_u:$fl_chown_g $(char_deescape_echo file_name_stitch_string)"
  3784. fi
  3785. fi
  3786. fi
  3787. else # If it's the last '<END', then do standard syntax checking for '<END'
  3788. fl_o=0
  3789. fl_f_list=0
  3790. fl_f_list_type=0
  3791. fi
  3792. fi
  3793. if (( $fl_f_list_type == 2 )); then
  3794. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3795. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3796. if (( $fl_I_a == 1 )); then
  3797. chmod $chmod_perm_string $(char_deescape_echo file_name_stitch_string)
  3798. fi
  3799. if (( $fl_I_g == 1 )); then
  3800. echo "chmod $chmod_perm_string $(char_deescape_echo file_name_stitch_string)"
  3801. fi
  3802. else # If it's the last '<END', then do standard syntax checking for '<END'
  3803. fl_o=0
  3804. fl_f_list=0
  3805. fl_f_list_type=0
  3806. fi
  3807. fi
  3808. if (( $fl_f_list_type == 3 )); then
  3809. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3810. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3811. if (( $fl_I_a == 1 )); then
  3812. chattr $chattr_arg_string$chattr_string $(char_deescape_echo file_name_stitch_string)
  3813. fi
  3814. if (( $fl_I_g == 1 )); then
  3815. echo "chattr $chattr_arg_string$chattr_string $(char_deescape_echo file_name_stitch_string)"
  3816. fi
  3817. else # If it's the last '<END', then do standard syntax checking for '<END'
  3818. fl_o=0
  3819. fl_f_list=0
  3820. fl_f_list_type=0
  3821. fl_chattr_recur=0
  3822. fl_chattr_verbose=0
  3823. fl_chattr_version=0
  3824. fl_chattr_version_c=0
  3825. chattr_version_no=0
  3826. chattr_no=0
  3827. chattr_file_no=0
  3828. chattr_string=""
  3829. chattr_arg_string=""
  3830. fi
  3831. fi
  3832. if (( $fl_f_list_type == 4 )); then
  3833. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3834. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3835. if (( $fl_I_a == 1 )); then
  3836. append_string_buffer=$(char_deescape_echo append_string_buffer)
  3837. echo -e "$append_string_buffer" >> $(char_deescape_echo file_name_stitch_string)
  3838. fi
  3839. if (( $fl_I_g == 1 )); then
  3840. append_string_buffer=$(char_deescape_echo append_string_buffer)
  3841. echo "echo -e \"$append_string_buffer\" >> $(char_deescape_echo file_name_stitch_string)"
  3842. fi
  3843. else
  3844. fl_o=0
  3845. fl_f_list=0
  3846. fl_f_list_type=0
  3847. fl_start_type=0
  3848. fl_w_list=0
  3849. fl_w_list_type=0
  3850. fl_append_specified=0
  3851. fl_append_string_first=1
  3852. append_string_buffer=""
  3853. fi
  3854. fi
  3855. if (( $fl_f_list_type == 5 )); then
  3856. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3857. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3858. if (( $fl_I_a == 1 )); then
  3859. for ((i=1; i <= $fl_insert_index; i++)); do
  3860. sed_mul_line_string=${insert_sed_mul_line_string_array[$i]}
  3861. insert_string_buffer_after=$(char_deescape_echo insert_string_buffer_after_array[$i])
  3862. insert_string_buffer_after=$(echo $insert_string_buffer_after | sed 's,/,\\\/,g')
  3863. insert_string_buffer=$(char_deescape_echo insert_string_buffer_array[$i])
  3864. insert_string_buffer=$(echo $insert_string_buffer | sed 's,/,\\\/,g')
  3865. insert_line_number=${insert_line_number_array[$i]}
  3866. if (( ${insert_line_or_after[$i]} == 0 )); then
  3867. insert_line_number=$(cat $(char_deescape_echo file_name_stitch_string) | sed -n "$sed_mul_line_string/$insert_string_buffer_after/=" | sed 'N;s/\n/ /g')
  3868. insert_line_number_array=()
  3869. j=0
  3870. temp5=0
  3871. for temp4 in $insert_line_number; do
  3872. insert_line_number_array[$j]=$temp4
  3873. ((j++))
  3874. done
  3875. for (( j=0; j < ${#insert_line_number_array[@]}; j++ )); do
  3876. if (( $j == $[${#insert_line_number_array[@]}-1] )) && (( $(cat $(char_deescape_echo file_name_stitch_string) | wc -l) == ${insert_line_number_array[$[${#insert_line_number_array[@]}-1]]} )); then
  3877. echo -ne "$insert_string_buffer" >> $(char_deescape_echo file_name_stitch_string)
  3878. else
  3879. IFS= temp3=$(cat $(char_deescape_echo file_name_stitch_string) | sed "$[${insert_line_number_array[$j]}+1+$temp5] i $insert_string_buffer")
  3880. ((temp5++))
  3881. echo -n $temp3 > $(char_deescape_echo file_name_stitch_string)
  3882. fi
  3883. done
  3884. else
  3885. if (( $(cat $(char_deescape_echo file_name_stitch_string) | wc -l) < $insert_line_number )); then
  3886. echo -ne "$insert_string_buffer" >> $(char_deescape_echo file_name_stitch_string)
  3887. else
  3888. IFS= temp3=$(cat $(char_deescape_echo file_name_stitch_string) | sed "$insert_line_number i $insert_string_buffer")
  3889. echo -n "$temp3" > $(char_deescape_echo file_name_stitch_string)
  3890. fi
  3891. fi
  3892. done
  3893. fi
  3894. if (( $fl_I_g == 1 )); then
  3895. for ((i=1; i <= $fl_insert_index; i++)); do
  3896. sed_mul_line_string=${insert_sed_mul_line_string_array[$i]}
  3897. insert_string_buffer_after=$(char_deescape_echo insert_string_buffer_after_array[$i])
  3898. insert_string_buffer_after=$(echo $insert_string_buffer_after | sed 's,/,\\\/,g')
  3899. insert_string_buffer=$(char_deescape_echo insert_string_buffer_array[$i])
  3900. insert_string_buffer=$(echo $insert_string_buffer | sed 's,/,\\\/,g')
  3901. insert_line_number=${insert_line_number_array[$i]}
  3902. if (( ${insert_line_or_after[$i]} == 0 )); then
  3903. echo "insert_line_number=\$(cat $(char_deescape_echo file_name_stitch_string) | sed -n '$sed_mul_line_string/$insert_string_buffer_after/=' | sed 'N;s/\n//g')"
  3904. echo "insert_line_number_array=()"
  3905. echo "j=0"
  3906. echo "temp3=0"
  3907. echo "for temp2 in \$insert_line_number; do"
  3908. echo "insert_line_number_array[\$j]=\$temp2"
  3909. echo "((j++))"
  3910. echo "done"
  3911. echo "for (( j=0; j < \${#insert_line_number_array[@]}; j++ )); do"
  3912. echo "if (( \$j == \$[\${#insert_line_number_array[@]}-1] )) && (( \$(cat $(char_deescape_echo file_name_stitch_string) | wc -l) == \${insert_line_number_array[\$[\${#insert_line_number_array[@]}-1]]} )); then"
  3913. echo "echo -ne $insert_string_buffer >> $(char_deescape_echo file_name_stitch_string)"
  3914. echo "else"
  3915. echo "IFS= temp=\$(cat $(char_deescape_echo file_name_stitch_string) | sed \"\$[\${insert_line_number_array[\$j]}+1+\$temp3] i $insert_string_buffer\")"
  3916. echo "((temp3++))"
  3917. echo "echo -n \$temp > $(char_deescape_echo file_name_stitch_string)"
  3918. echo "fi"
  3919. echo "done"
  3920. else
  3921. echo "if (( \$(cat $(char_deescape_echo file_name_stitch_string) | wc -l) < $insert_line_number )); then"
  3922. echo "echo -ne $insert_string_buffer >> $(char_deescape_echo file_name_stitch_string)"
  3923. echo "else"
  3924. echo "IFS= temp=\$(cat $(char_deescape_echo file_name_stitch_string) | sed \"$insert_line_number i $insert_string_buffer\")"
  3925. echo "echo -n \$temp > $(char_deescape_echo file_name_stitch_string)"
  3926. echo "fi"
  3927. fi
  3928. done
  3929. fi
  3930. else
  3931. fl_o=0
  3932. fl_f_list=0
  3933. fl_f_list_type=0
  3934. fl_start_type=0
  3935. fl_w_list=0
  3936. fl_w_list_type=0
  3937. fl_insert_specified=0
  3938. fl_insert_line=0
  3939. fl_insert_after=0
  3940. fl_insert_string_first=1
  3941. fl_insert_string_after_first=1
  3942. insert_string_buffer=""
  3943. insert_string_buffer_after=""
  3944. fl_insert_index=0
  3945. fi
  3946. fi
  3947. if (( $fl_f_list_type == 6 )); then
  3948. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  3949. filename_stitch_quiet line[@] file_name_stitch_string file_name_stitch_c c_error
  3950. if (( $fl_I_a == 1 )); then
  3951. for ((i=1; i <= $fl_replace_index; i++ )); do
  3952. sed_mul_line_string=${replace_sed_mul_line_string_array[$i]}
  3953. replace_string_buffer_with=$(char_deescape_echo replace_string_buffer_with_array[$i])
  3954. replace_string_buffer_with=$(echo $replace_string_buffer_with | sed 's,/,\\\/,g')
  3955. replace_string_buffer=$(char_deescape_echo replace_string_buffer_array[$i])
  3956. replace_string_buffer=$(echo $replace_string_buffer | sed 's,/,\\\/,g')
  3957. if (( $replace_mul_line == 1 )); then
  3958. IFS= temp3=$(cat $(char_deescape_echo file_name_stitch_string) | sed ':a;N;$!ba;'"s/$replace_string_buffer/$replace_string_buffer_with/g")
  3959. echo -n $temp3 > $(char_deescape_echo file_name_stitch_string)
  3960. else
  3961. IFS= temp3=$(cat $(char_deescape_echo file_name_stitch_string) | sed "s/$replace_string_buffer/$replace_string_buffer_with/g")
  3962. echo -n $temp3 > $(char_deescape_echo file_name_stitch_string)
  3963. fi
  3964. done
  3965. fi
  3966. if (( $fl_I_g == 1 )); then
  3967. for ((i=1; i <= $fl_replace_index; i++ )); do
  3968. sed_mul_line_string=${replace_sed_mul_line_string_array[$i]}
  3969. replace_string_buffer_with=$(char_deescape_echo replace_string_buffer_with_array[$i])
  3970. replace_string_buffer_with=$(echo $replace_string_buffer_with | sed 's,/,\\\/,g')
  3971. replace_string_buffer=$(char_deescape_echo replace_string_buffer_array[$i])
  3972. replace_string_buffer=$(echo $replace_string_buffer | sed 's,/,\\\/,g')
  3973. if (( $replace_mul_line == 1 )); then
  3974. echo "IFS= temp=\$(cat $(char_deescape_echo file_name_stitch_string) | sed ':a;N;\$!ba;''s/$replace_string_buffer/$replace_string_buffer_with/g')"
  3975. echo "echo \$temp > $(char_deescape_echo file_name_stitch_string)"
  3976. else
  3977. echo "IFS= temp=\$(cat $(char_deescape_echo file_name_stitch_string) | sed 's/$replace_string_buffer/$replace_string_buffer_with/g')"
  3978. echo "echo \$temp > $(char_deescape_echo file_name_stitch_string)"
  3979. fi
  3980. done
  3981. fi
  3982. else
  3983. fl_o=0
  3984. fl_f_list=0
  3985. fl_f_list_type=0
  3986. fl_start_type=0
  3987. fl_w_list=0
  3988. fl_w_list_type=0
  3989. fl_replace_specified=0
  3990. fl_replace_string_first=1
  3991. replace_string_buffer=""
  3992. fl_replace_with=0
  3993. replace_string_buffer_with=""
  3994. fl_replace_string_with_first=1
  3995. fl_replace_index=0
  3996. replace_mul_line=0
  3997. fi
  3998. fi
  3999. if (( $fl_f_list_type == 7 )); then
  4000. if [[ $line_no != $end_line_no ]]; then # If it's not the last '<END', process it as file name
  4001. ((nm_list_file_no++))
  4002. else
  4003. fl_o=0
  4004. fl_f_list=0
  4005. fl_f_list_type=0
  4006. fl_start_type=0
  4007. fl_w_list=0
  4008. fl_w_list_type=0
  4009. fl_nm_list_c=0
  4010. fl_nm_list_specified=0
  4011. ((nm_list_no++))
  4012. fi
  4013. fi
  4014. fi
  4015. ((line_no++))
  4016. unset line
  4017. done < "$filelist"
Advertisement
Add Comment
Please, Sign In to add comment