| @@ -240,53 +240,53 @@ readSizeT (const char *infopath, const c | | | @@ -240,53 +240,53 @@ readSizeT (const char *infopath, const c |
240 | case 'G': | | 240 | case 'G': |
241 | factor = xtimes (factor, 1024); | | 241 | factor = xtimes (factor, 1024); |
242 | case 'M': | | 242 | case 'M': |
243 | factor = xtimes (factor, 1024); | | 243 | factor = xtimes (factor, 1024); |
244 | case 'k': | | 244 | case 'k': |
245 | factor = xtimes (factor, 1024); | | 245 | factor = xtimes (factor, 1024); |
246 | break; | | 246 | break; |
247 | default: | | 247 | default: |
248 | error (0, 0, | | 248 | error (0, 0, |
249 | "%s: Unknown %s factor: `%c'", | | 249 | "%s: Unknown %s factor: `%c'", |
250 | infopath, option, p[strlen(p)]); | | 250 | infopath, option, p[strlen(p)]); |
251 | return false; | | 251 | return false; |
252 | } | | 252 | } |
253 | TRACE (TRACE_DATA, "readSizeT(): Found factor %u for %s", | | 253 | TRACE (TRACE_DATA, "readSizeT(): Found factor %zu for %s", |
254 | factor, option); | | 254 | factor, option); |
255 | } | | 255 | } |
256 | | | 256 | |
257 | /* Verify that *q is a number. */ | | 257 | /* Verify that *q is a number. */ |
258 | q = p; | | 258 | q = p; |
259 | while (q < p + strlen(p) - 1 /* Checked last character above. */) | | 259 | while (q < p + strlen(p) - 1 /* Checked last character above. */) |
260 | { | | 260 | { |
261 | if (!isdigit(*q)) | | 261 | if (!isdigit(*q)) |
262 | { | | 262 | { |
263 | error (0, 0, | | 263 | error (0, 0, |
264 | "%s: %s must be a postitive integer, not '%s'", | | 264 | "%s: %s must be a postitive integer, not '%s'", |
265 | infopath, option, p); | | 265 | infopath, option, p); |
266 | return false; | | 266 | return false; |
267 | } | | 267 | } |
268 | q++; | | 268 | q++; |
269 | } | | 269 | } |
270 | | | 270 | |
271 | /* Compute final value. */ | | 271 | /* Compute final value. */ |
272 | num = strtoul (p, NULL, 10); | | 272 | num = strtoul (p, NULL, 10); |
273 | if (num == ULONG_MAX || num > SIZE_MAX) | | 273 | if (num == ULONG_MAX || num > SIZE_MAX) |
274 | /* Don't return an error, just max out. */ | | 274 | /* Don't return an error, just max out. */ |
275 | num = SIZE_MAX; | | 275 | num = SIZE_MAX; |
276 | | | 276 | |
277 | TRACE (TRACE_DATA, "readSizeT(): read number %u for %s", num, option); | | 277 | TRACE (TRACE_DATA, "readSizeT(): read number %zu for %s", num, option); |
278 | *val = xtimes (strtoul (p, NULL, 10), factor); | | 278 | *val = xtimes (strtoul (p, NULL, 10), factor); |
279 | TRACE (TRACE_DATA, "readSizeT(): returnning %u for %s", *val, option); | | 279 | TRACE (TRACE_DATA, "readSizeT(): returnning %zu for %s", *val, option); |
280 | return true; | | 280 | return true; |
281 | } | | 281 | } |
282 | | | 282 | |
283 | | | 283 | |
284 | | | 284 | |
285 | /* Allocate and initialize a new config struct. */ | | 285 | /* Allocate and initialize a new config struct. */ |
286 | static inline struct config * | | 286 | static inline struct config * |
287 | new_config (void) | | 287 | new_config (void) |
288 | { | | 288 | { |
289 | struct config *new = xcalloc (1, sizeof (struct config)); | | 289 | struct config *new = xcalloc (1, sizeof (struct config)); |
290 | | | 290 | |
291 | TRACE (TRACE_FLOW, "new_config ()"); | | 291 | TRACE (TRACE_FLOW, "new_config ()"); |
292 | | | 292 | |
| @@ -721,13 +721,201 @@ parse_config (const char *cvsroot, const | | | @@ -721,13 +721,201 @@ parse_config (const char *cvsroot, const |
721 | if (!parse_error (infopath, ln)) | | 721 | if (!parse_error (infopath, ln)) |
722 | error (0, 0, "%s [%u]: unrecognized keyword `%s'", | | 722 | error (0, 0, "%s [%u]: unrecognized keyword `%s'", |
723 | infopath, ln, line); | | 723 | infopath, ln, line); |
724 | } | | 724 | } |
725 | if (ferror (fp_info)) | | 725 | if (ferror (fp_info)) |
726 | error (0, errno, "cannot read %s", infopath); | | 726 | error (0, errno, "cannot read %s", infopath); |
727 | if (fclose (fp_info) < 0) | | 727 | if (fclose (fp_info) < 0) |
728 | error (0, errno, "cannot close %s", infopath); | | 728 | error (0, errno, "cannot close %s", infopath); |
729 | if (freeinfopath) free (freeinfopath); | | 729 | if (freeinfopath) free (freeinfopath); |
730 | if (buf) free (buf); | | 730 | if (buf) free (buf); |
731 | | | 731 | |
732 | return retval; | | 732 | return retval; |
733 | } | | 733 | } |
| | | 734 | |
| | | 735 | /* cvsacl patch */ |
| | | 736 | int |
| | | 737 | parse_aclconfig (const char *cvsroot) |
| | | 738 | { |
| | | 739 | char *infopath; |
| | | 740 | FILE *fp_info; |
| | | 741 | char *line = NULL; |
| | | 742 | size_t line_allocated = 0; |
| | | 743 | size_t len; |
| | | 744 | char *p; |
| | | 745 | /* FIXME-reentrancy: If we do a multi-threaded server, this would need |
| | | 746 | to go to the per-connection data structures. */ |
| | | 747 | static int parsed = 0; |
| | | 748 | |
| | | 749 | /* Authentication code and serve_root might both want to call us. |
| | | 750 | Let this happen smoothly. */ |
| | | 751 | if (parsed) |
| | | 752 | return 0; |
| | | 753 | parsed = 1; |
| | | 754 | |
| | | 755 | infopath = xmalloc (strlen (cvsroot) |
| | | 756 | + sizeof (CVSROOTADM_ACLCONFIG) |
| | | 757 | + sizeof (CVSROOTADM) |
| | | 758 | + 10); |
| | | 759 | if (infopath == NULL) |
| | | 760 | { |
| | | 761 | error (0, 0, "out of memory; cannot allocate infopath"); |
| | | 762 | goto error_return; |
| | | 763 | } |
| | | 764 | |
| | | 765 | strcpy (infopath, cvsroot); |
| | | 766 | strcat (infopath, "/"); |
| | | 767 | strcat (infopath, CVSROOTADM); |
| | | 768 | strcat (infopath, "/"); |
| | | 769 | strcat (infopath, CVSROOTADM_ACLCONFIG); |
| | | 770 | |
| | | 771 | fp_info = CVS_FOPEN (infopath, "r"); |
| | | 772 | if (fp_info == NULL) |
| | | 773 | { |
| | | 774 | /* If no file, don't do anything special. */ |
| | | 775 | if (!existence_error (errno)) |
| | | 776 | { |
| | | 777 | /* Just a warning message; doesn't affect return |
| | | 778 | value, currently at least. */ |
| | | 779 | error (0, errno, "cannot open %s", infopath); |
| | | 780 | } |
| | | 781 | free (infopath); |
| | | 782 | return 0; |
| | | 783 | } |
| | | 784 | |
| | | 785 | while (getline (&line, &line_allocated, fp_info) >= 0) |
| | | 786 | { |
| | | 787 | /* Skip comments. */ |
| | | 788 | if (line[0] == '#') |
| | | 789 | continue; |
| | | 790 | |
| | | 791 | len = strlen (line) - 1; |
| | | 792 | if (line[len] == '\n') |
| | | 793 | line[len] = '\0'; |
| | | 794 | |
| | | 795 | /* Skip blank lines. */ |
| | | 796 | if (line[0] == '\0') |
| | | 797 | continue; |
| | | 798 | |
| | | 799 | /* The first '=' separates keyword from value. */ |
| | | 800 | p = strchr (line, '='); |
| | | 801 | if (p == NULL) |
| | | 802 | { |
| | | 803 | /* Probably should be printing line number. */ |
| | | 804 | error (0, 0, "syntax error in %s: line '%s' is missing '='", |
| | | 805 | infopath, line); |
| | | 806 | goto error_return; |
| | | 807 | } |
| | | 808 | |
| | | 809 | *p++ = '\0'; |
| | | 810 | |
| | | 811 | if (strcmp (line, "UseCVSACL") == 0) |
| | | 812 | { |
| | | 813 | if (strcmp (p, "no") == 0) |
| | | 814 | use_cvs_acl = 0; |
| | | 815 | else if (strcmp (p, "yes") == 0) |
| | | 816 | use_cvs_acl = 1; |
| | | 817 | else |
| | | 818 | { |
| | | 819 | error (0, 0, "unrecognized value '%s' for UseCVSACL", p); |
| | | 820 | goto error_return; |
| | | 821 | } |
| | | 822 | } |
| | | 823 | else if (strcmp (line, "UseSeperateACLFileForEachDir") == 0) |
| | | 824 | { |
| | | 825 | if (strcmp (p, "no") == 0) |
| | | 826 | use_separate_acl_file_for_each_dir = 0; |
| | | 827 | else if (strcmp (p, "yes") == 0) |
| | | 828 | use_separate_acl_file_for_each_dir = 1; |
| | | 829 | else |
| | | 830 | { |
| | | 831 | error (0, 0, "unrecognized value '%s' for UseSeperateACLFileForEachDir", p); |
| | | 832 | goto error_return; |
| | | 833 | } |
| | | 834 | } |
| | | 835 | else if (strcmp (line, "StopAtFirstPermissionDenied") == 0) |
| | | 836 | { |
| | | 837 | if (strcmp (p, "no") == 0) |
| | | 838 | stop_at_first_permission_denied = 0; |
| | | 839 | else if (strcmp (p, "yes") == 0) |
| | | 840 | stop_at_first_permission_denied = 1; |
| | | 841 | else |
| | | 842 | { |
| | | 843 | error (0, 0, "unrecognized value '%s' for StopAtFirstPermissionDenied", p); |
| | | 844 | goto error_return; |
| | | 845 | } |
| | | 846 | } |
| | | 847 | else if (strcmp (line, "CVSACLDefaultPermissions") == 0) |
| | | 848 | { |
| | | 849 | if (cvs_acl_default_permissions != NULL) |
| | | 850 | free (cvs_acl_default_permissions); |
| | | 851 | if (!given_perms_valid (p)) |
| | | 852 | error (1,0,"Invalid CVS ACL Default Permissions: '%s' in CVSROOT/aclconfig", p); |
| | | 853 | cvs_acl_default_permissions = xstrdup (p); |
| | | 854 | } |
| | | 855 | else if (strcmp (line, "UseCVSGroups") == 0) |
| | | 856 | { |
| | | 857 | if (strcmp (p, "no") == 0) |
| | | 858 | use_cvs_groups = 0; |
| | | 859 | else if (strcmp (p, "yes") == 0) |
| | | 860 | use_cvs_groups = 1; |
| | | 861 | else |
| | | 862 | { |
| | | 863 | error (0, 0, "unrecognized value '%s' for UseCVSGroups", p); |
| | | 864 | goto error_return; |
| | | 865 | } |
| | | 866 | } |
| | | 867 | else if (strcmp (line, "UseSystemGroups") == 0) |
| | | 868 | { |
| | | 869 | if (strcmp (p, "no") == 0) |
| | | 870 | use_system_groups = 0; |
| | | 871 | else if (strcmp (p, "yes") == 0) |
| | | 872 | use_system_groups = 1; |
| | | 873 | else |
| | | 874 | { |
| | | 875 | error (0, 0, "unrecognized value '%s' for UseSystemGroups", p); |
| | | 876 | goto error_return; |
| | | 877 | } |
| | | 878 | } |
| | | 879 | else if (strcmp (line, "CVSACLFileLocation") == 0) |
| | | 880 | { |
| | | 881 | if (cvs_acl_file_location != NULL) |
| | | 882 | free (cvs_acl_file_location); |
| | | 883 | cvs_acl_file_location = xstrdup (p); |
| | | 884 | } |
| | | 885 | else if (strcmp (line, "CVSGroupsFileLocation") == 0) |
| | | 886 | { |
| | | 887 | if (cvs_groups_file_location != NULL) |
| | | 888 | free (cvs_groups_file_location); |
| | | 889 | cvs_groups_file_location = xstrdup (p); |
| | | 890 | } |
| | | 891 | else if (strcmp (line, "CVSServerRunAsUser") == 0) |
| | | 892 | { |
| | | 893 | if (cvs_server_run_as != NULL) |
| | | 894 | free (cvs_server_run_as); |
| | | 895 | cvs_server_run_as = xstrdup (p); |
| | | 896 | } |
| | | 897 | |
| | | 898 | } |
| | | 899 | |
| | | 900 | if (ferror (fp_info)) |
| | | 901 | { |
| | | 902 | error (0, errno, "cannot read %s", infopath); |
| | | 903 | goto error_return; |
| | | 904 | } |
| | | 905 | if (fclose (fp_info) < 0) |
| | | 906 | { |
| | | 907 | error (0, errno, "cannot close %s", infopath); |
| | | 908 | goto error_return; |
| | | 909 | } |
| | | 910 | free (infopath); |
| | | 911 | if (line != NULL) |
| | | 912 | free (line); |
| | | 913 | return 0; |
| | | 914 | |
| | | 915 | error_return: |
| | | 916 | if (infopath != NULL) |
| | | 917 | free (infopath); |
| | | 918 | if (line != NULL) |
| | | 919 | free (line); |
| | | 920 | return -1; |
| | | 921 | } |