diff --git a/backport-Fix-memory-leaks-in-the-chcpu.patch b/backport-Fix-memory-leaks-in-the-chcpu.patch new file mode 100644 index 0000000000000000000000000000000000000000..2607013a8d74ab64097bf3594ac6df1b990ecf66 --- /dev/null +++ b/backport-Fix-memory-leaks-in-the-chcpu.patch @@ -0,0 +1,24 @@ +From 8757959ac2b64aa30cb748822c858c0c2d0410dd Mon Sep 17 00:00:00 2001 +From: jiazhenyuan +Date: Mon, 6 Sep 2021 16:50:27 +0800 +Subject: [PATCH] Fix memory leaks in the chcpu + +--- + sys-utils/chcpu.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sys-utils/chcpu.c b/sys-utils/chcpu.c +index c4e5bc7..527bce5 100644 +--- a/sys-utils/chcpu.c ++++ b/sys-utils/chcpu.c +@@ -383,6 +383,7 @@ int main(int argc, char *argv[]) + break; + } + ++ CPU_FREE(cpu_set); + ul_unref_path(sys); + + return rc == 0 ? EXIT_SUCCESS : +-- +1.8.3.1 + diff --git a/backport-Forward-value-of-sector_size-instead-of-its-address.patch b/backport-Forward-value-of-sector_size-instead-of-its-address.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b8fee17cf6b28fff647a270b87c1a6f91ae32f6 --- /dev/null +++ b/backport-Forward-value-of-sector_size-instead-of-its-address.patch @@ -0,0 +1,29 @@ +From 9b1d5d040d82db567c9ab0ea2b271b6d12e8969f Mon Sep 17 00:00:00 2001 +From: Nicolas Melot +Date: Sun, 1 Aug 2021 19:20:58 +0200 +Subject: [PATCH] Forward value of sector_size instead of its address in + blkdev_get_physector_size + +--- + lib/blkdev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/blkdev.c b/lib/blkdev.c +index c22853d..2d02fb8 100644 +--- a/lib/blkdev.c ++++ b/lib/blkdev.c +@@ -222,8 +222,10 @@ int blkdev_get_sector_size(int fd __attribute__((__unused__)), int *sector_size) + #ifdef BLKPBSZGET + int blkdev_get_physector_size(int fd, int *sector_size) + { +- if (ioctl(fd, BLKPBSZGET, §or_size) >= 0) ++ if (ioctl(fd, BLKPBSZGET, sector_size) >= 0) ++ { + return 0; ++ } + return -1; + } + #else +-- +1.8.3.1 + diff --git a/backport-libfdisk-check-calloc-return-gcc-analyzer.patch b/backport-libfdisk-check-calloc-return-gcc-analyzer.patch new file mode 100644 index 0000000000000000000000000000000000000000..d3ba60f1c4e7fd83f81f97701ea3f8b35cbefe3a --- /dev/null +++ b/backport-libfdisk-check-calloc-return-gcc-analyzer.patch @@ -0,0 +1,43 @@ +From e31e28848e7e5887b0dd48f5bb5ce3c8055eee1e Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 18 Aug 2021 11:35:07 +0200 +Subject: [PATCH] libfdisk: check calloc() return [gcc-analyzer] + +Signed-off-by: Karel Zak +--- + libfdisk/src/ask.c | 4 ++++ + libfdisk/src/item.c | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c +index 31f95fb..274f6ba 100644 +--- a/libfdisk/src/ask.c ++++ b/libfdisk/src/ask.c +@@ -36,6 +36,10 @@ int fdisk_set_ask(struct fdisk_context *cxt, + struct fdisk_ask *fdisk_new_ask(void) + { + struct fdisk_ask *ask = calloc(1, sizeof(struct fdisk_ask)); ++ ++ if (!ask) ++ return NULL; ++ + DBG(ASK, ul_debugobj(ask, "alloc")); + ask->refcount = 1; + return ask; +diff --git a/libfdisk/src/item.c b/libfdisk/src/item.c +index 86fa0fb..671f9ad 100644 +--- a/libfdisk/src/item.c ++++ b/libfdisk/src/item.c +@@ -40,6 +40,9 @@ struct fdisk_labelitem *fdisk_new_labelitem(void) + { + struct fdisk_labelitem *li = calloc(1, sizeof(*li)); + ++ if (!li) ++ return NULL; ++ + li->refcount = 1; + DBG(ITEM, ul_debugobj(li, "alloc")); + return li; +-- +1.8.3.1 + diff --git a/backport-libfdisk-dereference-of-possibly-NULL-gcc-analyzer.patch b/backport-libfdisk-dereference-of-possibly-NULL-gcc-analyzer.patch new file mode 100644 index 0000000000000000000000000000000000000000..c072b08f2b75eec0d2f3e89beea0278559e0ec8b --- /dev/null +++ b/backport-libfdisk-dereference-of-possibly-NULL-gcc-analyzer.patch @@ -0,0 +1,27 @@ +From fb1689c1de5fdc945c599aa46b483fa5e1333935 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 18 Aug 2021 11:15:55 +0200 +Subject: [PATCH] libfdisk: dereference of possibly-NULL [gcc-analyzer] + +Signed-off-by: Karel Zak +--- + libfdisk/src/parttype.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c +index 3a5db9c..271b671 100644 +--- a/libfdisk/src/parttype.c ++++ b/libfdisk/src/parttype.c +@@ -26,6 +26,9 @@ struct fdisk_parttype *fdisk_new_parttype(void) + { + struct fdisk_parttype *t = calloc(1, sizeof(*t)); + ++ if (!t) ++ return NULL; ++ + t->refcount = 1; + t->flags = FDISK_PARTTYPE_ALLOCATED; + DBG(PARTTYPE, ul_debugobj(t, "alloc")); +-- +1.8.3.1 + diff --git a/backport-logger-fix-prio-prefix-doesn-t-use-priority-default.patch b/backport-logger-fix-prio-prefix-doesn-t-use-priority-default.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d6e64d1401f458ab56d45f1fd1976ea539c95b5 --- /dev/null +++ b/backport-logger-fix-prio-prefix-doesn-t-use-priority-default.patch @@ -0,0 +1,37 @@ +From dbe693413205ba2c3d06a42e85b47b1bd713bfee Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 16 Sep 2021 12:20:25 +0200 +Subject: [PATCH] logger: fix --prio-prefix doesn't use --priority default + +The commit b9ef27f have added priority check, but it introduced +regression as the default priority (as specified by --priority) is +ignored. + +This patch fixes this problem, but it also removes extra check for +"kern facility", it's unnecessary and inconsistent with the rest of +logger. + +Fixes: https://github.com/karelzak/util-linux/issues/1450 +Signed-off-by: Karel Zak +--- + misc-utils/logger.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/misc-utils/logger.c b/misc-utils/logger.c +index 5b122de..0e7ac8d 100644 +--- a/misc-utils/logger.c ++++ b/misc-utils/logger.c +@@ -997,8 +997,8 @@ static void logger_stdin(struct logger_ctl *ctl) + if (c == '>' && 0 <= pri && pri <= 191) { + /* valid RFC PRI values */ + i = 0; +- if (pri < 8) /* kern facility is forbidden */ +- pri |= 8; ++ if ((pri & LOG_FACMASK) == 0) ++ pri |= (default_priority & LOG_FACMASK); + ctl->pri = pri; + } else + ctl->pri = default_priority; +-- +1.8.3.1 + diff --git a/backport-login-Restore-tty-size-after-calling-vhangup.patch b/backport-login-Restore-tty-size-after-calling-vhangup.patch new file mode 100644 index 0000000000000000000000000000000000000000..530d35a79db392a8c06c93a1fe33ddde3ff70375 --- /dev/null +++ b/backport-login-Restore-tty-size-after-calling-vhangup.patch @@ -0,0 +1,58 @@ +From 7ba741a50a04e8e72861e90132394996f2d82006 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Sat, 30 Oct 2021 15:56:14 +0100 +Subject: [PATCH] login: Restore tty size after calling vhangup() + +If login receives the tty to work on via stdin, stdout and stderr, +login might end up closing the remaining open file descriptors to +the tty just before it calls vhangup(). When the last open file +descriptors to a tty are closed, it's configured size is reset to +0x0. To avoid this from happening, save the size before closing +the stdin, stdout and stderr file descriptors and reapply the size +after the tty is re-opened. + +Fixes #1484 +--- + login-utils/login.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/login-utils/login.c b/login-utils/login.c +index 3657f04..c9f6d59 100644 +--- a/login-utils/login.c ++++ b/login-utils/login.c +@@ -513,6 +513,7 @@ static void init_tty(struct login_context *cxt) + { + struct stat st; + struct termios tt, ttt; ++ struct winsize ws; + + cxt->tty_mode = (mode_t) getlogindefs_num("TTYPERM", TTY_MODE); + +@@ -543,6 +544,12 @@ static void init_tty(struct login_context *cxt) + } + #endif + ++ /* The TTY size might be reset to 0x0 by the kernel when we close the stdin/stdout/stderr file ++ * descriptors so let's save the size now so we can reapply it later */ ++ memset(&ws, 0, sizeof(struct winsize)); ++ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) ++ syslog(LOG_WARNING, _("TIOCGWINSZ ioctl failed: %m")); ++ + tcgetattr(0, &tt); + ttt = tt; + ttt.c_cflag &= ~HUPCL; +@@ -574,6 +581,11 @@ static void init_tty(struct login_context *cxt) + + /* restore tty modes */ + tcsetattr(0, TCSAFLUSH, &tt); ++ ++ /* Restore tty size */ ++ if (ws.ws_row > 0 || ws.ws_col > 0) ++ if (ioctl(STDIN_FILENO, TIOCSWINSZ, &ws) < 0) ++ syslog(LOG_WARNING, _("TIOCSWINSZ ioctl failed: %m")); + } + + /* +-- +1.8.3.1 + diff --git a/backport-mcookie-fix-infinite-loop-when-use-f.patch b/backport-mcookie-fix-infinite-loop-when-use-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..9dbb05ac2ea2fe6e0523429bea2f4b6501591dff --- /dev/null +++ b/backport-mcookie-fix-infinite-loop-when-use-f.patch @@ -0,0 +1,26 @@ +From d380bf23fd68ebc2799eabcd86fb43de797b93d8 Mon Sep 17 00:00:00 2001 +From: Hiroaki Sengoku +Date: Fri, 15 Oct 2021 14:02:46 +0900 +Subject: [PATCH] mcookie: fix infinite-loop when use -f + +Signed-off-by: Karel Zak +--- + misc-utils/mcookie.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc-utils/mcookie.c b/misc-utils/mcookie.c +index 3157401..be5c34a 100644 +--- a/misc-utils/mcookie.c ++++ b/misc-utils/mcookie.c +@@ -65,7 +65,7 @@ static uint64_t hash_file(struct mcookie_control *ctl, int fd) + rdsz = wanted - count; + + r = read_all(fd, (char *) buf, rdsz); +- if (r < 0) ++ if (r <= 0) + break; + ul_MD5Update(&ctl->ctx, buf, r); + count += r; +-- +1.8.3.1 + diff --git a/backport-sfdisk-write-empty-label-also-when-only-ignored-part.patch b/backport-sfdisk-write-empty-label-also-when-only-ignored-part.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d00d396a32144108bfe26fd976646219143b726 --- /dev/null +++ b/backport-sfdisk-write-empty-label-also-when-only-ignored-part.patch @@ -0,0 +1,51 @@ +From 9e9ad25d690b284427f9a355475bcdddb17cf1e0 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 19 Aug 2021 12:10:02 +0200 +Subject: [PATCH] sfdisk: write empty label also when only ignored partition + specified + +sfdisk writes empty disk label only when "label:" header specified. +Unfortunately, this feature is ignored when all specified partitions +are ignored + + echo -e "label: dos\n0,0,0\n" | sfdisk /dev/sdc + +Fixes: https://github.com/karelzak/util-linux/issues/1413 +Signed-off-by: Karel Zak +--- + disk-utils/sfdisk.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c +index 526d090..b08c945 100644 +--- a/disk-utils/sfdisk.c ++++ b/disk-utils/sfdisk.c +@@ -1714,7 +1714,7 @@ static void refresh_prompt_buffer(struct sfdisk *sf, const char *devname, + */ + static int command_fdisk(struct sfdisk *sf, int argc, char **argv) + { +- int rc = 0, partno = sf->partno, created = 0, unused = 0; ++ int rc = 0, partno = sf->partno, created = 0, unused = 0, ignored = 0; + struct fdisk_script *dp; + struct fdisk_table *tb = NULL; + const char *devname = NULL, *label; +@@ -1897,6 +1897,7 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) + if (ignore_partition(pa)) { + fdisk_info(sf->cxt, _("Ignoring partition.")); + next_partno++; ++ ignored++; + continue; + } + if (!created) { /* create a new disklabel */ +@@ -1960,7 +1961,7 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) + /* create empty disk label if label, but no partition specified */ + if ((rc == SFDISK_DONE_EOF || rc == SFDISK_DONE_WRITE) && created == 0 + && fdisk_script_has_force_label(dp) == 1 +- && fdisk_table_get_nents(tb) == 0 ++ && fdisk_table_get_nents(tb) == (size_t) ignored + && fdisk_script_get_header(dp, "label")) { + + int xrc = fdisk_apply_script_headers(sf->cxt, dp); +-- +1.8.3.1 + diff --git a/backport-su-bash-completion-offer-usernames-rather-than-files.patch b/backport-su-bash-completion-offer-usernames-rather-than-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..11f723db3ef2756620377479710225271cf9fc3b --- /dev/null +++ b/backport-su-bash-completion-offer-usernames-rather-than-files.patch @@ -0,0 +1,27 @@ +From 49609c78e9441dab686da4eda38df1dcca3cacc9 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 31 Aug 2021 12:51:40 +0200 +Subject: [PATCH] su: (bash-completion) offer usernames rather than files + +Fixes: https://github.com/karelzak/util-linux/issues/1424 +Signed-off-by: Karel Zak +--- + bash-completion/su | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bash-completion/su b/bash-completion/su +index 3095050..913e445 100644 +--- a/bash-completion/su ++++ b/bash-completion/su +@@ -41,7 +41,7 @@ _su_module() + esac + local IFS=$'\n' + compopt -o filenames +- COMPREPLY=( $(compgen -f -- $cur) ) ++ COMPREPLY=( $(compgen -u -- $cur) ) + return 0 + } + complete -F _su_module su +-- +1.8.3.1 + diff --git a/backport-vipw-flush-stdout-before-getting-answer.patch b/backport-vipw-flush-stdout-before-getting-answer.patch new file mode 100644 index 0000000000000000000000000000000000000000..82b9cca0ddd4fa38054f40db7f4d89783cf31b65 --- /dev/null +++ b/backport-vipw-flush-stdout-before-getting-answer.patch @@ -0,0 +1,35 @@ +From 56bacb552d017858751aac208987604f7c9387c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89rico=20Nogueira?= +Date: Fri, 22 Oct 2021 14:28:50 -0300 +Subject: [PATCH] vipw: flush stdout before getting answer. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise the question is displayed only after the user presses Return, +and the program looks like it's hanging. + +This happens at least on musl libc. + +Reported by @loreb. + +Signed-off-by: Érico Nogueira +--- + login-utils/vipw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/login-utils/vipw.c b/login-utils/vipw.c +index f178c8f..bf76f51 100644 +--- a/login-utils/vipw.c ++++ b/login-utils/vipw.c +@@ -353,6 +353,7 @@ int main(int argc, char *argv[]) + * which means they can be translated. */ + printf(_("Would you like to edit %s now [y/n]? "), orig_file); + ++ fflush(stdout); + if (fgets(response, sizeof(response), stdin) && + rpmatch(response) == RPMATCH_YES) + edit_file(1); +-- +1.8.3.1 + diff --git a/util-linux.spec b/util-linux.spec index fff61eb7d5a62228041ada56fd5c5b33a24ddae7..fa71dcc948136a9ba8ba4a886e2152351daa49d9 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -1,9 +1,9 @@ %define compldir %{_datadir}/bash-completion/completions/ -%global upstream_major 2.36 +%global upstream_major 2.37 Name: util-linux Version: 2.37.2 -Release: 3 +Release: 4 Summary: A random collection of Linux utilities License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git @@ -21,6 +21,16 @@ Source9: util-linux-runuser-l.pamd Patch0: 2.36-login-lastlog-create.patch Patch1: Add-check-to-resolve-uname26-version-test-failed.patch Patch2: SKIPPED-no-root-permissions-test.patch +Patch3: backport-su-bash-completion-offer-usernames-rather-than-files.patch +Patch4: backport-Fix-memory-leaks-in-the-chcpu.patch +Patch5: backport-logger-fix-prio-prefix-doesn-t-use-priority-default.patch +Patch6: backport-vipw-flush-stdout-before-getting-answer.patch +Patch7: backport-login-Restore-tty-size-after-calling-vhangup.patch +Patch8: backport-Forward-value-of-sector_size-instead-of-its-address.patch +Patch9: backport-libfdisk-dereference-of-possibly-NULL-gcc-analyzer.patch +Patch10: backport-libfdisk-check-calloc-return-gcc-analyzer.patch +Patch11: backport-mcookie-fix-infinite-loop-when-use-f.patch +Patch12: backport-sfdisk-write-empty-label-also-when-only-ignored-part.patch BuildRequires: audit-libs-devel >= 1.0.6 gettext-devel libselinux-devel ncurses-devel pam-devel zlib-devel popt-devel BuildRequires: libutempter-devel systemd-devel systemd libuser-devel libcap-ng-devel python3-devel gcc @@ -30,15 +40,15 @@ Requires: pam >= 1.1.3-7, /etc/pam.d/system-auth audit-libs >= 1.0.6 Requires: libblkid = %{version}-%{release} libmount = %{version}-%{release} libsmartcols = %{version}-%{release} Requires: libfdisk = %{version}-%{release} libuuid = %{version}-%{release} -Conflicts: initscripts < 9.79-4 bash-completion < 1:2.1-1 coreutils < 8.20 sysvinit-tools < 2.88-14 +Conflicts: initscripts < 9.79-4 bash-completion < 1:2.1-1 coreutils < 8.20 Conflicts: e2fsprogs < 1.41.8-5 filesystem < 3 Provides: eject = 2.1.6 rfkill = 0.5 Provides: util-linux-ng = %{version}-%{release} hardlink = 1:1.3-9 Provides: /bin/dmesg /bin/kill /bin/more /bin/mount /bin/umount /sbin/blkid Provides: /sbin/blockdev /sbin/findfs /sbin/fsck /sbin/nologin -Obsoletes: eject <= 2.1.5 rfkill <= 0.5 util-linux-ng < 2.19 hardlink <= 1:1.3-9 - +Provides: /bin/last /bin/lastb /bin/mesg /bin/wall +Obsoletes: eject <= 2.1.5 rfkill <= 0.5 util-linux-ng < 2.19 hardlink <= 1:1.3-9 sysvinit-tools < 0:2.89 %description The util-linux package contains a random collection of files that @@ -168,7 +178,6 @@ unset LINGUAS || : %make_build %{_build_arg0__} %{_build_arg1__} %check -export TS_OPT_misc_setarch_known_fail="yes" make check %install @@ -297,7 +306,7 @@ fi %ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/mtab %{_unitdir}/fstrim.* %{_bindir}/{cal,chrt,col,colcrt,colrm,column,chmem,dmesg,eject,fallocate,fincore,findmnt,choom,uclampset} -%{_bindir}/{flock,getopt,hexdump,ionice,ipcmk,ipcrm,ipcs,isosize,kill,last,lastb,logger,hardlink} +%{_bindir}/{flock,getopt,ionice,ipcmk,ipcrm,ipcs,isosize,kill,last,lastb,logger,hardlink} %{_bindir}/{look,lsblk,lscpu,lsipc,lslocks,lslogins,lsmem,lsns,mcookie,mesg,more,mountpoint} %{_bindir}/{namei,nsenter,prlimit,raw,rename,renice,rev,script,scriptreplay,setarch,setpriv} %{_bindir}/{setsid,setterm,taskset,ul,unshare,utmpdump,uuidgen,uuidparse,wdctl,whereis,scriptlive,irqtop,lsirq} @@ -309,7 +318,7 @@ fi %{compldir}/{addpart,blkdiscard,blkid,blkzone,blockdev,cal,chcpu,chmem,chrt,col} %{compldir}/{colcrt,colrm,column,ctrlaltdel,delpart,dmesg,eject,fallocate,fdisk} %{compldir}/{fincore,findfs,findmnt,flock,fsck,fsck.cramfs,fsck.minix,fsfreeze} -%{compldir}/{fstrim,getopt,hexdump,ionice,ipcmk,ipcrm,ipcs,isosize,last,ldattach} +%{compldir}/{fstrim,getopt,ionice,ipcmk,ipcrm,ipcs,isosize,last,ldattach} %{compldir}/{logger,look,losetup,lsblk,lscpu,lsipc,lslocks,lslogins,lsmem,lsns} %{compldir}/{mcookie,mesg,mkfs,mkfs.cramfs,mkfs.minix,mkswap,more,mountpoint} %{compldir}/{namei,nsenter,partx,pivot_root,prlimit,raw,readprofile,rename,renice} @@ -363,6 +372,8 @@ fi %{_includedir}/{libfdisk,libsmartcols,uuid,blkid,libmount} %{_libdir}/{libfdisk.so,libsmartcols.so,libuuid.so,libblkid.so,libmount.so} %{_libdir}/pkgconfig/{fdisk.pc,smartcols.pc,uuid.pc,blkid.pc,mount.pc} +%{_bindir}/hexdump +%{compldir}/hexdump %files help %exclude %{_datadir}/doc/util-linux/getopt/* @@ -387,6 +398,14 @@ fi %{_mandir}/man8/{swapoff.8*,swapon.8*,switch_root.8*,umount.8*,wdctl.8.gz,wipefs.8*,zramctl.8*} %changelog +* Mon Jun 20 2022 shangyibin - 2.37.2-4 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:sync patches + move hexdump from util-linux to util-linux-devel + solve yum failure because of files conflicts + * Wed Jun 15 2022 shangyibin - 2.37.2-3 - Type:bugfix - ID:NA