| udev.h | | udev.h | |
| | | | |
| skipping to change at line 42 | | skipping to change at line 42 | |
| #define ALARM_TIMEOUT 120 | | #define ALARM_TIMEOUT 120 | |
| #define COMMENT_CHARACTER '#' | | #define COMMENT_CHARACTER '#' | |
| | | | |
| #define LINE_SIZE 512 | | #define LINE_SIZE 512 | |
| #define NAME_SIZE 128 | | #define NAME_SIZE 128 | |
| #define PATH_SIZE 256 | | #define PATH_SIZE 256 | |
| #define USER_SIZE 32 | | #define USER_SIZE 32 | |
| #define SEQNUM_SIZE 32 | | #define SEQNUM_SIZE 32 | |
| #define VALUE_SIZE 128 | | #define VALUE_SIZE 128 | |
| | | | |
|
| #define DEVD_DIR "/etc/dev.d" | | | |
| #define DEVD_SUFFIX ".dev" | | | |
| | | | |
| #define HOTPLUGD_DIR "/etc/hotplug.d" | | | |
| #define HOTPLUG_SUFFIX ".hotplug" | | | |
| | | | |
| #define DEFAULT_PARTITIONS_COUNT 15 | | #define DEFAULT_PARTITIONS_COUNT 15 | |
| | | | |
| enum device_type { | | enum device_type { | |
| DEV_UNKNOWN, | | DEV_UNKNOWN, | |
| DEV_CLASS, | | DEV_CLASS, | |
| DEV_BLOCK, | | DEV_BLOCK, | |
| DEV_NET, | | DEV_NET, | |
| DEV_DEVICE, | | DEV_DEVICE, | |
| }; | | }; | |
| | | | |
| struct udevice { | | struct udevice { | |
| char devpath[PATH_SIZE]; | | char devpath[PATH_SIZE]; | |
| char subsystem[NAME_SIZE]; | | char subsystem[NAME_SIZE]; | |
| char action[NAME_SIZE]; | | char action[NAME_SIZE]; | |
| | | | |
| enum device_type type; | | enum device_type type; | |
| char name[PATH_SIZE]; | | char name[PATH_SIZE]; | |
|
| | | int name_set; | |
| char devname[PATH_SIZE]; | | char devname[PATH_SIZE]; | |
| struct list_head symlink_list; | | struct list_head symlink_list; | |
|
| | | int symlink_final; | |
| char owner[USER_SIZE]; | | char owner[USER_SIZE]; | |
|
| | | int owner_final; | |
| char group[USER_SIZE]; | | char group[USER_SIZE]; | |
|
| | | int group_final; | |
| mode_t mode; | | mode_t mode; | |
|
| | | int mode_final; | |
| dev_t devt; | | dev_t devt; | |
| struct list_head run_list; | | struct list_head run_list; | |
|
| | | int run_final; | |
| | | struct list_head env_list; | |
| | | | |
| char tmp_node[PATH_SIZE]; | | char tmp_node[PATH_SIZE]; | |
| int partitions; | | int partitions; | |
| int ignore_device; | | int ignore_device; | |
| int ignore_remove; | | int ignore_remove; | |
| int config_line; | | int config_line; | |
| char config_file[PATH_SIZE]; | | char config_file[PATH_SIZE]; | |
| char bus_id[NAME_SIZE]; | | char bus_id[NAME_SIZE]; | |
| char program_result[PATH_SIZE]; | | char program_result[PATH_SIZE]; | |
| char kernel_number[NAME_SIZE]; | | char kernel_number[NAME_SIZE]; | |
| char kernel_name[NAME_SIZE]; | | char kernel_name[NAME_SIZE]; | |
| int test_run; | | int test_run; | |
| }; | | }; | |
| | | | |
| extern int udev_add_device(struct udevice *udev, struct sysfs_class_device
*class_dev); | | extern int udev_add_device(struct udevice *udev, struct sysfs_class_device
*class_dev); | |
| extern int udev_remove_device(struct udevice *udev); | | extern int udev_remove_device(struct udevice *udev); | |
| extern void udev_init_config(void); | | extern void udev_init_config(void); | |
| extern int udev_start(void); | | extern int udev_start(void); | |
|
| extern void udev_multiplex_directory(struct udevice *udev, const char *base
dir, const char *suffix); | | | |
| extern int udev_make_node(struct udevice *udev, const char *file, dev_t dev
t, mode_t mode, uid_t uid, gid_t gid); | | extern int udev_make_node(struct udevice *udev, const char *file, dev_t dev
t, mode_t mode, uid_t uid, gid_t gid); | |
| | | | |
| extern char sysfs_path[PATH_SIZE]; | | extern char sysfs_path[PATH_SIZE]; | |
| extern char udev_root[PATH_SIZE]; | | extern char udev_root[PATH_SIZE]; | |
| extern char udev_db_path[PATH_SIZE]; | | extern char udev_db_path[PATH_SIZE]; | |
| extern char udev_config_filename[PATH_SIZE]; | | extern char udev_config_filename[PATH_SIZE]; | |
| extern char udev_rules_filename[PATH_SIZE]; | | extern char udev_rules_filename[PATH_SIZE]; | |
| extern int udev_log_priority; | | extern int udev_log_priority; | |
| extern int udev_run; | | extern int udev_run; | |
|
| extern int udev_dev_d; | | | |
| extern int udev_hotplug_d; | | | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 9 change blocks. |
| 9 lines changed or deleted | | 7 lines changed or added | |
|
| udev_libc_wrapper.h | | udev_libc_wrapper.h | |
| | | | |
| skipping to change at line 47 | | skipping to change at line 47 | |
| #endif | | #endif | |
| #ifndef __FD_ISSET | | #ifndef __FD_ISSET | |
| #define __FD_ISSET(d, set) (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) !=
0) | | #define __FD_ISSET(d, set) (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) !=
0) | |
| #endif | | #endif | |
| #ifndef __FD_ZERO | | #ifndef __FD_ZERO | |
| #define __FD_ZERO(set) ((void) memset ((void*) (set), 0, sizeof (fd_set))) | | #define __FD_ZERO(set) ((void) memset ((void*) (set), 0, sizeof (fd_set))) | |
| #endif | | #endif | |
| | | | |
| #include <string.h> | | #include <string.h> | |
| | | | |
|
| | | #ifdef __KLIBC__ | |
| | | static inline int clearenv(void) | |
| | | { | |
| | | environ[0] = NULL; | |
| | | return 0; | |
| | | } | |
| | | #endif | |
| | | | |
| extern uid_t lookup_user(const char *user); | | extern uid_t lookup_user(const char *user); | |
| extern gid_t lookup_group(const char *group); | | extern gid_t lookup_group(const char *group); | |
| | | | |
|
| #ifndef strlcat | | | |
| extern size_t strlcpy(char *dst, const char *src, size_t size); | | extern size_t strlcpy(char *dst, const char *src, size_t size); | |
|
| #endif | | | |
| | | | |
| #ifndef strlcat | | | |
| extern size_t strlcat(char *dst, const char *src, size_t size); | | extern size_t strlcat(char *dst, const char *src, size_t size); | |
|
| #endif | | | |
| | | | |
| #endif /* _UDEV_LIBC_WRAPPER_H_ */ | | #endif /* _UDEV_LIBC_WRAPPER_H_ */ | |
| | | | |
End of changes. 4 change blocks. |
| 5 lines changed or deleted | | 8 lines changed or added | |
|
| udev_rules.h | | udev_rules.h | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| #ifndef UDEV_RULES_H | | #ifndef UDEV_RULES_H | |
| #define UDEV_RULES_H | | #define UDEV_RULES_H | |
| | | | |
| #include "libsysfs/sysfs/libsysfs.h" | | #include "libsysfs/sysfs/libsysfs.h" | |
| #include "udev.h" | | #include "udev.h" | |
| #include "list.h" | | #include "list.h" | |
| | | | |
| #define KEY_KERNEL "KERNEL" | | #define KEY_KERNEL "KERNEL" | |
| #define KEY_SUBSYSTEM "SUBSYSTEM" | | #define KEY_SUBSYSTEM "SUBSYSTEM" | |
| #define KEY_ACTION "ACTION" | | #define KEY_ACTION "ACTION" | |
|
| | | #define KEY_DEVPATH "DEVPATH" | |
| #define KEY_BUS "BUS" | | #define KEY_BUS "BUS" | |
| #define KEY_ID "ID" | | #define KEY_ID "ID" | |
| #define KEY_PROGRAM "PROGRAM" | | #define KEY_PROGRAM "PROGRAM" | |
| #define KEY_RESULT "RESULT" | | #define KEY_RESULT "RESULT" | |
| #define KEY_DRIVER "DRIVER" | | #define KEY_DRIVER "DRIVER" | |
| #define KEY_SYSFS "SYSFS" | | #define KEY_SYSFS "SYSFS" | |
| #define KEY_ENV "ENV" | | #define KEY_ENV "ENV" | |
|
| | | #define KEY_MODALIAS "MODALIAS" | |
| | | #define KEY_IMPORT "IMPORT" | |
| #define KEY_NAME "NAME" | | #define KEY_NAME "NAME" | |
| #define KEY_SYMLINK "SYMLINK" | | #define KEY_SYMLINK "SYMLINK" | |
| #define KEY_OWNER "OWNER" | | #define KEY_OWNER "OWNER" | |
| #define KEY_GROUP "GROUP" | | #define KEY_GROUP "GROUP" | |
| #define KEY_MODE "MODE" | | #define KEY_MODE "MODE" | |
| #define KEY_RUN "RUN" | | #define KEY_RUN "RUN" | |
| #define KEY_OPTIONS "OPTIONS" | | #define KEY_OPTIONS "OPTIONS" | |
| | | | |
| #define OPTION_LAST_RULE "last_rule" | | #define OPTION_LAST_RULE "last_rule" | |
| #define OPTION_IGNORE_DEVICE "ignore_device" | | #define OPTION_IGNORE_DEVICE "ignore_device" | |
| | | | |
| skipping to change at line 64 | | skipping to change at line 67 | |
| #define KEY_ENV_PAIRS_MAX 5 | | #define KEY_ENV_PAIRS_MAX 5 | |
| | | | |
| #define RULEFILE_SUFFIX ".rules" | | #define RULEFILE_SUFFIX ".rules" | |
| | | | |
| enum key_operation { | | enum key_operation { | |
| KEY_OP_UNSET, | | KEY_OP_UNSET, | |
| KEY_OP_MATCH, | | KEY_OP_MATCH, | |
| KEY_OP_NOMATCH, | | KEY_OP_NOMATCH, | |
| KEY_OP_ADD, | | KEY_OP_ADD, | |
| KEY_OP_ASSIGN, | | KEY_OP_ASSIGN, | |
|
| | | KEY_OP_ASSIGN_FINAL, | |
| }; | | }; | |
| | | | |
| struct key_pair { | | struct key_pair { | |
| char name[NAME_SIZE]; | | char name[NAME_SIZE]; | |
| char value[VALUE_SIZE]; | | char value[VALUE_SIZE]; | |
| enum key_operation operation; | | enum key_operation operation; | |
| }; | | }; | |
| | | | |
| struct udev_rule { | | struct udev_rule { | |
| struct list_head node; | | struct list_head node; | |
| | | | |
| char kernel[NAME_SIZE]; | | char kernel[NAME_SIZE]; | |
| enum key_operation kernel_operation; | | enum key_operation kernel_operation; | |
| char subsystem[NAME_SIZE]; | | char subsystem[NAME_SIZE]; | |
| enum key_operation subsystem_operation; | | enum key_operation subsystem_operation; | |
| char action[NAME_SIZE]; | | char action[NAME_SIZE]; | |
| enum key_operation action_operation; | | enum key_operation action_operation; | |
|
| | | char devpath[PATH_SIZE]; | |
| | | enum key_operation devpath_operation; | |
| char bus[NAME_SIZE]; | | char bus[NAME_SIZE]; | |
| enum key_operation bus_operation; | | enum key_operation bus_operation; | |
| char id[NAME_SIZE]; | | char id[NAME_SIZE]; | |
| enum key_operation id_operation; | | enum key_operation id_operation; | |
| char driver[NAME_SIZE]; | | char driver[NAME_SIZE]; | |
| enum key_operation driver_operation; | | enum key_operation driver_operation; | |
| char program[PATH_SIZE]; | | char program[PATH_SIZE]; | |
| enum key_operation program_operation; | | enum key_operation program_operation; | |
| char result[PATH_SIZE]; | | char result[PATH_SIZE]; | |
| enum key_operation result_operation; | | enum key_operation result_operation; | |
| struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX]; | | struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX]; | |
| int sysfs_pair_count; | | int sysfs_pair_count; | |
| struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; | | struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; | |
| int env_pair_count; | | int env_pair_count; | |
|
| | | char modalias[NAME_SIZE]; | |
| | | enum key_operation modalias_operation; | |
| | | char import[PATH_SIZE]; | |
| | | enum key_operation import_operation; | |
| | | int import_exec; | |
| | | | |
| char name[PATH_SIZE]; | | char name[PATH_SIZE]; | |
|
| | | enum key_operation name_operation; | |
| char symlink[PATH_SIZE]; | | char symlink[PATH_SIZE]; | |
|
| | | enum key_operation symlink_operation; | |
| char owner[USER_SIZE]; | | char owner[USER_SIZE]; | |
|
| | | enum key_operation owner_operation; | |
| char group[USER_SIZE]; | | char group[USER_SIZE]; | |
|
| | | enum key_operation group_operation; | |
| mode_t mode; | | mode_t mode; | |
|
| | | enum key_operation mode_operation; | |
| char run[PATH_SIZE]; | | char run[PATH_SIZE]; | |
|
| | | enum key_operation run_operation; | |
| | | | |
| int last_rule; | | int last_rule; | |
| int ignore_device; | | int ignore_device; | |
| int ignore_remove; | | int ignore_remove; | |
| int partitions; | | int partitions; | |
| | | | |
| char config_file[PATH_SIZE]; | | char config_file[PATH_SIZE]; | |
| int config_line; | | int config_line; | |
| }; | | }; | |
| | | | |
|
| extern struct list_head udev_rule_list; | | | |
| | | | |
| extern int udev_rules_init(void); | | extern int udev_rules_init(void); | |
|
| extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_dev | | | |
| ice *class_dev); | | | |
| extern int udev_rules_get_run(struct udevice *udev); | | | |
| extern void udev_rules_close(void); | | extern void udev_rules_close(void); | |
| | | | |
|
| | | extern int udev_rules_iter_init(void); | |
| | | extern struct udev_rule *udev_rules_iter_next(void); | |
| | | | |
| | | extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_dev | |
| | | ice *class_dev); | |
| | | extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sy | |
| | | sfs_device); | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 14 change blocks. |
| 5 lines changed or deleted | | 25 lines changed or added | |
|
| udev_sysfs.h | | udev_sysfs.h | |
| | | | |
| skipping to change at line 27 | | skipping to change at line 27 | |
| * with this program; if not, write to the Free Software Foundation, In
c., | | * with this program; if not, write to the Free Software Foundation, In
c., | |
| * 675 Mass Ave, Cambridge, MA 02139, USA. | | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | | * | |
| */ | | */ | |
| | | | |
| #ifndef _UDEV_SYSFS_H_ | | #ifndef _UDEV_SYSFS_H_ | |
| #define _UDEV_SYSFS_H_ | | #define _UDEV_SYSFS_H_ | |
| | | | |
| #include "libsysfs/sysfs/libsysfs.h" | | #include "libsysfs/sysfs/libsysfs.h" | |
| | | | |
|
| #define WAIT_MAX_SECONDS 5 | | #define WAIT_MAX_SECONDS 3 | |
| #define WAIT_LOOP_PER_SECOND 20 | | #define WAIT_LOOP_PER_SECOND 20 | |
| | | | |
| extern dev_t get_devt(struct sysfs_class_device *class_dev); | | extern dev_t get_devt(struct sysfs_class_device *class_dev); | |
| extern int subsystem_expect_no_dev(const char *subsystem); | | extern int subsystem_expect_no_dev(const char *subsystem); | |
| | | | |
| /* /sys/class /sys/block devices */ | | /* /sys/class /sys/block devices */ | |
| extern struct sysfs_class_device *wait_class_device_open(const char *path); | | extern struct sysfs_class_device *wait_class_device_open(const char *path); | |
| extern int wait_for_class_device(struct sysfs_class_device *class_dev, cons
t char **error); | | extern int wait_for_class_device(struct sysfs_class_device *class_dev, cons
t char **error); | |
| | | | |
| /* /sys/devices devices */ | | /* /sys/devices devices */ | |
| | | | |
End of changes. 1 change blocks. |
| 1 lines changed or deleted | | 1 lines changed or added | |
|
| udev_utils.h | | udev_utils.h | |
| | | | |
| skipping to change at line 37 | | skipping to change at line 37 | |
| struct name_entry { | | struct name_entry { | |
| struct list_head node; | | struct list_head node; | |
| char name[PATH_SIZE]; | | char name[PATH_SIZE]; | |
| }; | | }; | |
| | | | |
| extern int udev_init_device(struct udevice *udev, const char* devpath, cons
t char *subsystem, const char *action); | | extern int udev_init_device(struct udevice *udev, const char* devpath, cons
t char *subsystem, const char *action); | |
| extern void udev_cleanup_device(struct udevice *udev); | | extern void udev_cleanup_device(struct udevice *udev); | |
| | | | |
| extern int kernel_release_satisfactory(unsigned int version, unsigned int p
atchlevel, unsigned int sublevel); | | extern int kernel_release_satisfactory(unsigned int version, unsigned int p
atchlevel, unsigned int sublevel); | |
| extern int create_path(const char *path); | | extern int create_path(const char *path); | |
|
| | | extern int log_priority(const char *priority); | |
| | | extern int string_is_true(const char *str); | |
| extern int parse_get_pair(char **orig_string, char **left, char **right); | | extern int parse_get_pair(char **orig_string, char **left, char **right); | |
| extern int unlink_secure(const char *filename); | | extern int unlink_secure(const char *filename); | |
| extern int file_map(const char *filename, char **buf, size_t *bufsize); | | extern int file_map(const char *filename, char **buf, size_t *bufsize); | |
|
| extern void file_unmap(char *buf, size_t bufsize); | | extern void file_unmap(void *buf, size_t bufsize); | |
| extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); | | extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); | |
| extern void remove_trailing_char(char *path, char c); | | extern void remove_trailing_char(char *path, char c); | |
| extern void replace_untrusted_chars(char *string); | | extern void replace_untrusted_chars(char *string); | |
| extern int name_list_add(struct list_head *name_list, const char *name, int
sort); | | extern int name_list_add(struct list_head *name_list, const char *name, int
sort); | |
|
| | | extern int name_list_key_add(struct list_head *name_list, const char *key,
const char *value); | |
| extern int add_matching_files(struct list_head *name_list, const char *dirn
ame, const char *suffix); | | extern int add_matching_files(struct list_head *name_list, const char *dirn
ame, const char *suffix); | |
|
| extern int execute_command(const char *command, const char *subsystem); | | extern int execute_program(const char *command, const char *subsystem, | |
| | | char *result, size_t ressize, size_t *reslen); | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 4 change blocks. |
| 2 lines changed or deleted | | 6 lines changed or added | |
|
| udevd.h | | udevd.h | |
| | | | |
| skipping to change at line 29 | | skipping to change at line 29 | |
| * You should have received a copy of the GNU General Public License al
ong | | * You should have received a copy of the GNU General Public License al
ong | |
| * with this program; if not, write to the Free Software Foundation, In
c., | | * with this program; if not, write to the Free Software Foundation, In
c., | |
| * 675 Mass Ave, Cambridge, MA 02139, USA. | | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | | * | |
| */ | | */ | |
| | | | |
| #include "list.h" | | #include "list.h" | |
| | | | |
| #define UDEV_MAGIC "udevd_" UDEV_VERSION | | #define UDEV_MAGIC "udevd_" UDEV_VERSION | |
| #define UDEVD_SOCK_PATH "udevd" | | #define UDEVD_SOCK_PATH "udevd" | |
|
| #define SEND_WAIT_MAX_SECONDS 3 | | #define UDEVSEND_WAIT_MAX_SECONDS 3 | |
| #define SEND_WAIT_LOOP_PER_SECOND 10 | | #define UDEVSEND_WAIT_LOOP_PER_SECOND 10 | |
| | | | |
| #define UDEVD_PRIORITY -4 | | #define UDEVD_PRIORITY -4 | |
| #define UDEV_PRIORITY -2 | | #define UDEV_PRIORITY -2 | |
| | | | |
| /* duration of initialization phase with shorter timeout */ | | /* duration of initialization phase with shorter timeout */ | |
|
| #define INIT_TIME_SEC 5 | | #define UDEVD_INIT_TIME 5 | |
| #define EVENT_INIT_TIMEOUT_SEC 2 | | #define UDEVD_INIT_EVENT_TIMEOUT 2 | |
| | | | |
| /* timeout to wait for missing events */ | | /* timeout to wait for missing events */ | |
|
| #define EVENT_TIMEOUT_SEC 10 | | #define UDEVD_EVENT_TIMEOUT 5 | |
| | | | |
|
| | | /* maximum limit of runnig childs */ | |
| | | #define UDEVD_MAX_CHILDS 64 | |
| /* start to throttle forking if maximum number of running childs in our ses
sion is reached */ | | /* start to throttle forking if maximum number of running childs in our ses
sion is reached */ | |
|
| #define THROTTLE_MAX_RUNNING_CHILDS 10 | | #define UDEVD_MAX_CHILDS_RUNNING 8 | |
| | | | |
| /* environment buffer, should match the kernel's size in lib/kobject_uevent
.h */ | | /* environment buffer, should match the kernel's size in lib/kobject_uevent
.h */ | |
|
| #define HOTPLUG_BUFFER_SIZE 1024 | | #define UEVENT_BUFFER_SIZE 1024 | |
| #define HOTPLUG_NUM_ENVP 32 | | #define UEVENT_NUM_ENVP 32 | |
| | | | |
|
| struct udevsend_msg { | | enum udevd_msg_type { | |
| char magic[20]; | | UDEVD_UNKNOWN, | |
| char envbuf[HOTPLUG_BUFFER_SIZE+256]; | | UDEVD_UEVENT_UDEVSEND, | |
| | | UDEVD_UEVENT_INITSEND, | |
| | | UDEVD_UEVENT_NETLINK, | |
| | | UDEVD_STOP_EXEC_QUEUE, | |
| | | UDEVD_START_EXEC_QUEUE, | |
| | | UDEVD_SET_LOG_LEVEL, | |
| | | UDEVD_SET_MAX_CHILDS, | |
| }; | | }; | |
| | | | |
|
| struct hotplug_msg { | | struct udevd_msg { | |
| | | char magic[32]; | |
| | | enum udevd_msg_type type; | |
| | | char envbuf[UEVENT_BUFFER_SIZE+512]; | |
| | | }; | |
| | | | |
| | | struct uevent_msg { | |
| | | enum udevd_msg_type type; | |
| struct list_head node; | | struct list_head node; | |
| pid_t pid; | | pid_t pid; | |
| long queue_time; | | long queue_time; | |
| char *action; | | char *action; | |
| char *devpath; | | char *devpath; | |
| char *subsystem; | | char *subsystem; | |
| unsigned long long seqnum; | | unsigned long long seqnum; | |
| char *physdevpath; | | char *physdevpath; | |
| unsigned int timeout; | | unsigned int timeout; | |
|
| char *envp[HOTPLUG_NUM_ENVP+1]; | | char *envp[UEVENT_NUM_ENVP+1]; | |
| char envbuf[]; | | char envbuf[]; | |
| }; | | }; | |
| | | | |
End of changes. 9 change blocks. |
| 13 lines changed or deleted | | 28 lines changed or added | |
|