diff --git a/0001-treewide-sys-poll-to-poll.patch b/0001-treewide-sys-poll-to-poll.patch new file mode 100644 index 0000000..2821047 --- /dev/null +++ b/0001-treewide-sys-poll-to-poll.patch @@ -0,0 +1,87 @@ +From 5e6df5ae4ba587ba324dd97b7bd8af9f8159f59a Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Tue, 19 Nov 2019 20:28:53 -0800 +Subject: [PATCH 01/26] treewide: sys/poll to poll + +Fixes warning on musl: + +warning redirecting incorrect #include to + +Signed-off-by: Rosen Penev +Signed-off-by: Takashi Iwai +--- + amidi/amidi.c | 2 +- + amixer/amixer.c | 2 +- + aplay/aplay.c | 2 +- + seq/aplaymidi/arecordmidi.c | 2 +- + seq/aseqdump/aseqdump.c | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/amidi/amidi.c b/amidi/amidi.c +index b6e05e159031..c6268e4c2ccd 100644 +--- a/amidi/amidi.c ++++ b/amidi/amidi.c +@@ -31,7 +31,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +diff --git a/amixer/amixer.c b/amixer/amixer.c +index ad9c482e87e4..f7f31f0167fb 100644 +--- a/amixer/amixer.c ++++ b/amixer/amixer.c +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include + #include + #include "amixer.h" + #include "../alsamixer/volume_mapping.h" +diff --git a/aplay/aplay.c b/aplay/aplay.c +index 274bbce33dd2..52410684b47e 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -44,7 +44,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +diff --git a/seq/aplaymidi/arecordmidi.c b/seq/aplaymidi/arecordmidi.c +index f3db65ee8b91..604cd0d29722 100644 +--- a/seq/aplaymidi/arecordmidi.c ++++ b/seq/aplaymidi/arecordmidi.c +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include ++#include + #include + #include "aconfig.h" + #include "version.h" +diff --git a/seq/aseqdump/aseqdump.c b/seq/aseqdump/aseqdump.c +index 790454020259..578e06fbcb22 100644 +--- a/seq/aseqdump/aseqdump.c ++++ b/seq/aseqdump/aseqdump.c +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include ++#include + #include + #include "aconfig.h" + #include "version.h" +-- +2.16.4 + diff --git a/0002-treewide-Fix-wrong-formats-on-32-bit.patch b/0002-treewide-Fix-wrong-formats-on-32-bit.patch new file mode 100644 index 0000000..32d3a80 --- /dev/null +++ b/0002-treewide-Fix-wrong-formats-on-32-bit.patch @@ -0,0 +1,74 @@ +From 66e9a816093c7d8fbdfbc407062daabe89825b35 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Tue, 19 Nov 2019 20:28:54 -0800 +Subject: [PATCH 02/26] treewide: Fix wrong formats on 32-bit + +uint64_t evaluates to unsigned long long on 32-bit, not unsigned long. +Use the proper formats. + +Signed-off-by: Rosen Penev +Signed-off-by: Takashi Iwai +--- + axfer/container.c | 7 ++++--- + axfer/subcmd-transfer.c | 4 +++- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/axfer/container.c b/axfer/container.c +index 7da97c671927..566acd058636 100644 +--- a/axfer/container.c ++++ b/axfer/container.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + static const char *const cntr_type_labels[] = { + [CONTAINER_TYPE_PARSER] = "parser", +@@ -356,10 +357,10 @@ int container_context_pre_process(struct container_context *cntr, + fprintf(stderr, " frames/second: %u\n", + cntr->frames_per_second); + if (cntr->type == CONTAINER_TYPE_PARSER) { +- fprintf(stderr, " frames: %lu\n", ++ fprintf(stderr, " frames: %" PRIu64 "\n", + *frame_count); + } else { +- fprintf(stderr, " max frames: %lu\n", ++ fprintf(stderr, " max frames: %" PRIu64 "\n", + *frame_count); + } + } +@@ -427,7 +428,7 @@ int container_context_post_process(struct container_context *cntr, + assert(frame_count); + + if (cntr->verbose && cntr->handled_byte_count > 0) { +- fprintf(stderr, " Handled bytes: %lu\n", ++ fprintf(stderr, " Handled bytes: %" PRIu64 "\n", + cntr->handled_byte_count); + } + +diff --git a/axfer/subcmd-transfer.c b/axfer/subcmd-transfer.c +index 3ca745a6d7a1..8746e6f494d2 100644 +--- a/axfer/subcmd-transfer.c ++++ b/axfer/subcmd-transfer.c +@@ -11,6 +11,7 @@ + #include "misc.h" + + #include ++#include + + struct context { + struct xfer_context xfer; +@@ -389,7 +390,8 @@ static int context_process_frames(struct context *ctx, + + if (!ctx->xfer.quiet) { + fprintf(stderr, +- "%s: Expected %lu frames, Actual %lu frames\n", ++ "%s: Expected %" PRIu64 "frames, " ++ "Actual %" PRIu64 "frames\n", + snd_pcm_stream_name(direction), expected_frame_count, + *actual_frame_count); + if (ctx->interrupted) { +-- +2.16.4 + diff --git a/0003-treewide-Fix-printf-formats.patch b/0003-treewide-Fix-printf-formats.patch new file mode 100644 index 0000000..467e80c --- /dev/null +++ b/0003-treewide-Fix-printf-formats.patch @@ -0,0 +1,174 @@ +From 80fd81f4a8647fe2b62a02db9a497d2a7639d9e3 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Tue, 19 Nov 2019 20:28:55 -0800 +Subject: [PATCH 03/26] treewide: Fix printf formats + +Found with cppcheck + +Signed-off-by: Rosen Penev +Signed-off-by: Takashi Iwai +--- + alsactl/init_parse.c | 4 ++-- + alsaloop/pcmjob.c | 10 +++++----- + amixer/amixer.c | 6 +++--- + aplay/aplay.c | 2 +- + axfer/subcmd-list.c | 2 +- + axfer/xfer-libffado.c | 2 +- + axfer/xfer-options.c | 2 +- + 7 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/alsactl/init_parse.c b/alsactl/init_parse.c +index 562e67459c15..c048fd3e18b8 100644 +--- a/alsactl/init_parse.c ++++ b/alsactl/init_parse.c +@@ -187,7 +187,7 @@ static int init_space(struct space **space, int card) + return -ENOMEM; + res->ctl_id_changed = ~0; + res->linenum = -1; +- sprintf(device, "hw:%u", card); ++ sprintf(device, "hw:%d", card); + err = snd_hctl_open(&res->ctl_handle, device, 0); + if (err < 0) + goto error; +@@ -734,7 +734,7 @@ dbvalue: + elem = snd_hctl_elem_next(elem); + } + snd_ctl_elem_id_free(id); +- sprintf(res, "%u", index); ++ sprintf(res, "%d", index); + dbg("do_ctl_count found %s controls", res); + return res; + } +diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c +index 29d1aba85811..b252486b2f6d 100644 +--- a/alsaloop/pcmjob.c ++++ b/alsaloop/pcmjob.c +@@ -120,7 +120,7 @@ static int setparams_stream(struct loopback_handle *lhandle, + } + err = snd_pcm_hw_params_set_rate_resample(handle, params, lhandle->resample); + if (err < 0) { +- logit(LOG_CRIT, "Resample setup failed for %s (val %i): %s\n", lhandle->id, lhandle->resample, snd_strerror(err)); ++ logit(LOG_CRIT, "Resample setup failed for %s (val %u): %s\n", lhandle->id, lhandle->resample, snd_strerror(err)); + return err; + } + err = snd_pcm_hw_params_set_access(handle, params, lhandle->access); +@@ -135,13 +135,13 @@ static int setparams_stream(struct loopback_handle *lhandle, + } + err = snd_pcm_hw_params_set_channels(handle, params, lhandle->channels); + if (err < 0) { +- logit(LOG_CRIT, "Channels count (%i) not available for %s: %s\n", lhandle->channels, lhandle->id, snd_strerror(err)); ++ logit(LOG_CRIT, "Channels count (%u) not available for %s: %s\n", lhandle->channels, lhandle->id, snd_strerror(err)); + return err; + } + rrate = lhandle->rate_req; + err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0); + if (err < 0) { +- logit(LOG_CRIT, "Rate %iHz not available for %s: %s\n", lhandle->rate_req, lhandle->id, snd_strerror(err)); ++ logit(LOG_CRIT, "Rate %uHz not available for %s: %s\n", lhandle->rate_req, lhandle->id, snd_strerror(err)); + return err; + } + rrate = 0; +@@ -152,7 +152,7 @@ static int setparams_stream(struct loopback_handle *lhandle, + !lhandle->loopback->src_enable && + #endif + (int)rrate != lhandle->rate) { +- logit(LOG_CRIT, "Rate does not match (requested %iHz, got %iHz, resample %i)\n", lhandle->rate, rrate, lhandle->resample); ++ logit(LOG_CRIT, "Rate does not match (requested %uHz, got %uHz, resample %u)\n", lhandle->rate, rrate, lhandle->resample); + return -EINVAL; + } + lhandle->pitch = (double)lhandle->rate_req / (double)lhandle->rate; +@@ -1613,7 +1613,7 @@ __again: + if (count > loop->play->buffer_size) + count = loop->play->buffer_size; + if (err != count) { +- logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%i)\n", loop->id, err, (int)count, loop->play->buffer_size); ++ logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%u)\n", loop->id, err, (int)count, loop->play->buffer_size); + err = -EIO; + goto __error; + } +diff --git a/amixer/amixer.c b/amixer/amixer.c +index f7f31f0167fb..928f7c5d6482 100644 +--- a/amixer/amixer.c ++++ b/amixer/amixer.c +@@ -465,7 +465,7 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_ + size = tlv[idx++]; + tlv_size -= 2 * sizeof(unsigned int); + if (size > tlv_size) { +- printf("TLV size error (%i, %i, %i)!\n", type, size, tlv_size); ++ printf("TLV size error (%u, %u, %u)!\n", type, size, tlv_size); + return; + } + switch (type) { +@@ -576,7 +576,7 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_ + break; + #endif + default: +- printf("unk-%i-", type); ++ printf("unk-%u-", type); + while (size > 0) { + printf("0x%08x,", tlv[idx++]); + size -= sizeof(unsigned int); +@@ -611,7 +611,7 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, + } + count = snd_ctl_elem_info_get_count(info); + type = snd_ctl_elem_info_get_type(info); +- printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count); ++ printf("%s; type=%s,access=%s,values=%u", space, control_type(info), control_access(info), count); + switch (type) { + case SND_CTL_ELEM_TYPE_INTEGER: + printf(",min=%li,max=%li,step=%li\n", +diff --git a/aplay/aplay.c b/aplay/aplay.c +index 52410684b47e..72fa5676172f 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -3346,7 +3346,7 @@ static void playbackv(char **names, unsigned int count) + } + alloced = 1; + } else if (count != channels) { +- error(_("You need to specify %d files"), channels); ++ error(_("You need to specify %u files"), channels); + prg_exit(EXIT_FAILURE); + } + +diff --git a/axfer/subcmd-list.c b/axfer/subcmd-list.c +index e22628cbedb0..359f73f701a7 100644 +--- a/axfer/subcmd-list.c ++++ b/axfer/subcmd-list.c +@@ -31,7 +31,7 @@ static int dump_device(snd_ctl_t *handle, const char *id, const char *name, + snd_pcm_info_get_name(info)); + + count = snd_pcm_info_get_subdevices_count(info); +- printf(" Subdevices: %i/%i\n", ++ printf(" Subdevices: %i/%u\n", + snd_pcm_info_get_subdevices_avail(info), count); + + for (i = 0; i < count; ++i) { +diff --git a/axfer/xfer-libffado.c b/axfer/xfer-libffado.c +index a37cce68d209..6db835d6a9fa 100644 +--- a/axfer/xfer-libffado.c ++++ b/axfer/xfer-libffado.c +@@ -440,7 +440,7 @@ static int xfer_libffado_pre_process(struct xfer_context *xfer, + } + if (*samples_per_frame != channels) { + fprintf(stderr, +- "The number of samples per frame should be %i.\n", ++ "The number of samples per frame should be %u.\n", + channels); + return -EINVAL; + } +diff --git a/axfer/xfer-options.c b/axfer/xfer-options.c +index 352d126660a5..3740b166565d 100644 +--- a/axfer/xfer-options.c ++++ b/axfer/xfer-options.c +@@ -238,7 +238,7 @@ static int validate_options(struct xfer_context *xfer) + xfer->frames_per_second *= 1000; + if (xfer->frames_per_second < 2000 || + xfer->frames_per_second > 192000) { +- fprintf(stderr, "bad speed value '%i'\n", val); ++ fprintf(stderr, "bad speed value '%u'\n", val); + return -EINVAL; + } + +-- +2.16.4 + diff --git a/0004-aplay-Adjust-buffer-sizes-to-fix-snprintf-warnings.patch b/0004-aplay-Adjust-buffer-sizes-to-fix-snprintf-warnings.patch new file mode 100644 index 0000000..0450021 --- /dev/null +++ b/0004-aplay-Adjust-buffer-sizes-to-fix-snprintf-warnings.patch @@ -0,0 +1,81 @@ +From ac82b651676303e0689b1c23ad72aaf7b264ce5f Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Wed, 20 Nov 2019 10:19:20 -0800 +Subject: [PATCH 04/26] aplay: Adjust buffer sizes to fix snprintf warnings + +It also reduces compiled size slightly. + +aplay.c: In function 'capture': +aplay.c:3055:34: error: '-01' directive output may be truncated writing 3 +bytes into a region of size between 1 and 4097 [-Werror=format-truncation= +] + 3055 | snprintf(namebuf, namelen, "%s-01", buf); + | ^~~ +aplay.c:3055:4: note: 'snprintf' output between 4 and 4100 bytes into a +destination of size 4097 + 3055 | snprintf(namebuf, namelen, "%s-01", buf); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +aplay.c:3053:34: error: '-01.' directive output may be truncated writing 4 +bytes into a region of size between 1 and 4097 [-Werror=format-truncation= +] + 3053 | snprintf(namebuf, namelen, "%s-01.%s", buf, s); + | ^~~~ +aplay.c:3053:4: note: 'snprintf' output 5 or more bytes (assuming 4101) +into a destination of size 4097 + 3053 | snprintf(namebuf, namelen, "%s-01.%s", buf, s); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +aplay.c:3065:34: error: '%02i' directive output may be truncated writing +between 2 and 10 bytes into a region of size between 0 and 4096 [-Werror= +format-truncation=] + 3065 | snprintf(namebuf, namelen, "%s-%02i", buf, filecount); + | ^~~~ +aplay.c:3065:30: note: directive argument in the range [1, 2147483647] + 3065 | snprintf(namebuf, namelen, "%s-%02i", buf, filecount); + | ^~~~~~~~~ +aplay.c:3065:3: note: 'snprintf' output between 4 and 4108 bytes into a +destination of size 4097 + 3065 | snprintf(namebuf, namelen, "%s-%02i", buf, filecount); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +aplay.c:3063:34: error: '%02i' directive output may be truncated writing +between 2 and 10 bytes into a region of size between 0 and 4096 [-Werror= +format-truncation=] + 3063 | snprintf(namebuf, namelen, "%s-%02i.%s", buf, filecount, s); + | ^~~~ +aplay.c:3063:30: note: directive argument in the range [1, 2147483647] + 3063 | snprintf(namebuf, namelen, "%s-%02i.%s", buf, filecount, s); + | ^~~~~~~~~~~~ +aplay.c:3063:3: note: 'snprintf' output 5 or more bytes (assuming 4109) +into a destination of size 4097 + 3063 | snprintf(namebuf, namelen, "%s-%02i.%s", buf, filecount, s); + +Signed-off-by: Rosen Penev +Signed-off-by: Takashi Iwai +--- + aplay/aplay.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/aplay/aplay.c b/aplay/aplay.c +index 72fa5676172f..78adee2fa380 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -3015,7 +3015,7 @@ static int new_capture_file(char *name, char *namebuf, size_t namelen, + int filecount) + { + char *s; +- char buf[PATH_MAX+1]; ++ char buf[PATH_MAX-10]; + time_t t; + struct tm *tmp; + +@@ -3122,7 +3122,7 @@ static void capture(char *orig_name) + int tostdout=0; /* boolean which describes output stream */ + int filecount=0; /* number of files written */ + char *name = orig_name; /* current filename */ +- char namebuf[PATH_MAX+1]; ++ char namebuf[PATH_MAX+2]; + off64_t count, rest; /* number of bytes to capture */ + struct stat statbuf; + +-- +2.16.4 + diff --git a/0005-aplay-Limit-VUMeter-progress-bar-to-100-for-negative.patch b/0005-aplay-Limit-VUMeter-progress-bar-to-100-for-negative.patch new file mode 100644 index 0000000..27f17cc --- /dev/null +++ b/0005-aplay-Limit-VUMeter-progress-bar-to-100-for-negative.patch @@ -0,0 +1,44 @@ +From c9dc401264ad3c0b621f52e8098e7c1661c50cea Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Wed, 20 Nov 2019 11:13:55 -0800 +Subject: [PATCH 05/26] aplay: Limit VUMeter progress bar to 100 for negative + as well + +While the progress bar cannot be negative, GCC concludes that it can be +and assumes tmp can be written past the end. Fixes this GCC warning: + +aplay.c:1747:18: warning: '%02d' directive writing between 2 and 11 bytes + into a region of size 4 [-Wformat-overflow=] + 1747 | sprintf(tmp, "%02d%%", maxperc[c]); + +Signed-off-by: Rosen Penev +Signed-off-by: Takashi Iwai +--- + aplay/aplay.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/aplay/aplay.c b/aplay/aplay.c +index 78adee2fa380..1a887e412aae 100644 +--- a/aplay/aplay.c ++++ b/aplay/aplay.c +@@ -54,6 +54,8 @@ + #include "formats.h" + #include "version.h" + ++#define ABS(a) (a) < 0 ? -(a) : (a) ++ + #ifdef SND_CHMAP_API_VERSION + #define CONFIG_SUPPORT_CHMAP 1 + #endif +@@ -1741,7 +1743,7 @@ static void print_vu_meter_stereo(int *perc, int *maxperc) + line[bar_length + 6 + 1 + p] = '+'; + else + line[bar_length - p - 1] = '+'; +- if (maxperc[c] > 99) ++ if (ABS(maxperc[c]) > 99) + sprintf(tmp, "MAX"); + else + sprintf(tmp, "%02d%%", maxperc[c]); +-- +2.16.4 + diff --git a/0006-alsactl-sysfs-add-sys-kernel-uevent_seqnum-check-to-.patch b/0006-alsactl-sysfs-add-sys-kernel-uevent_seqnum-check-to-.patch new file mode 100644 index 0000000..fb17a72 --- /dev/null +++ b/0006-alsactl-sysfs-add-sys-kernel-uevent_seqnum-check-to-.patch @@ -0,0 +1,48 @@ +From 3c740d90490abe64c86c667934ba5d990817b873 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 20 Nov 2019 13:20:39 +0100 +Subject: [PATCH 06/26] alsactl: sysfs - add /sys/kernel/uevent_seqnum check to + init + +Signed-off-by: Jaroslav Kysela +--- + alsactl/init_sysfs.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/alsactl/init_sysfs.c b/alsactl/init_sysfs.c +index 5c789b61b0e5..57ef615a2c76 100644 +--- a/alsactl/init_sysfs.c ++++ b/alsactl/init_sysfs.c +@@ -34,6 +34,8 @@ static int sysfs_init(void) + const char *env; + char sysfs_test[PATH_SIZE]; + ++ INIT_LIST_HEAD(&attr_list); ++ + env = getenv("SYSFS_PATH"); + if (env) { + strlcpy(sysfs_path, env, sizeof(sysfs_path)); +@@ -43,13 +45,16 @@ static int sysfs_init(void) + dbg("sysfs_path='%s'", sysfs_path); + + strlcpy(sysfs_test, sysfs_path, sizeof(sysfs_test)); +- strlcat(sysfs_test, "/kernel/uevent_helper", sizeof(sysfs_test)); ++ strlcat(sysfs_test, "/kernel/uevent_seqnum", sizeof(sysfs_test)); + if (access(sysfs_test, F_OK)) { +- error("sysfs path '%s' is invalid\n", sysfs_path); +- return -errno; ++ strlcpy(sysfs_test, sysfs_path, sizeof(sysfs_test)); ++ strlcat(sysfs_test, "/kernel/uevent_helper", sizeof(sysfs_test)); ++ if (access(sysfs_test, F_OK)) { ++ error("sysfs path '%s' is invalid", sysfs_path); ++ return -errno; ++ } + } + +- INIT_LIST_HEAD(&attr_list); + return 0; + } + +-- +2.16.4 + diff --git a/0007-alsaucm-use-the-first-sound-card-use-case-name-hw-CA.patch b/0007-alsaucm-use-the-first-sound-card-use-case-name-hw-CA.patch new file mode 100644 index 0000000..ced703e --- /dev/null +++ b/0007-alsaucm-use-the-first-sound-card-use-case-name-hw-CA.patch @@ -0,0 +1,43 @@ +From 745c5df26066de94622dd38c667da31ac6b88510 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 25 Nov 2019 17:58:51 +0100 +Subject: [PATCH 07/26] alsaucm: use the first sound card (use case name + 'hw:CARDNO') as default + +Signed-off-by: Jaroslav Kysela +--- + alsaucm/usecase.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +--- a/alsaucm/usecase.c ++++ b/alsaucm/usecase.c +@@ -188,22 +188,19 @@ static void my_exit(struct context *cont + + static void do_initial_open(struct context *context) + { +- const char **list; +- int err; ++ int card, err; ++ char name[16]; + + if (!context->no_open && context->card == NULL) { +- err = snd_use_case_card_list(&list); ++ card = -1; ++ err = snd_card_next(&card); + if (err < 0) { +- fprintf(stderr, "%s: unable to obtain card list: %s\n", ++ fprintf(stderr, "%s: no sound card found: %s\n", + context->command, snd_strerror(err)); + my_exit(context, EXIT_FAILURE); + } +- if (err == 0) { +- printf("No card found\n"); +- my_exit(context, EXIT_SUCCESS); +- } +- context->card = strdup(list[0]); +- snd_use_case_free_list(list, err); ++ snprintf(name, sizeof(name), "hw:%d", card); ++ context->card = strdup(name); + } + + /* open library */ diff --git a/0008-alsaucm-add-text-dump-command.patch b/0008-alsaucm-add-text-dump-command.patch new file mode 100644 index 0000000..8d74c7c --- /dev/null +++ b/0008-alsaucm-add-text-dump-command.patch @@ -0,0 +1,559 @@ +From 860ffda82518dad6018f877f58aed1485d49e3a0 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 27 Nov 2019 08:51:29 +0100 +Subject: [PATCH 08/26] alsaucm: add text dump command + +Signed-off-by: Jaroslav Kysela +--- + alsaucm/Makefile.am | 2 +- + alsaucm/dump.c | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + alsaucm/usecase.c | 22 ++- + alsaucm/usecase.h | 35 +++++ + 4 files changed, 447 insertions(+), 15 deletions(-) + create mode 100644 alsaucm/dump.c + create mode 100644 alsaucm/usecase.h + +diff --git a/alsaucm/Makefile.am b/alsaucm/Makefile.am +index 4b447dd6758a..03f99e030a88 100644 +--- a/alsaucm/Makefile.am ++++ b/alsaucm/Makefile.am +@@ -5,7 +5,7 @@ if USE_RST2MAN + man_MANS = alsaucm.1 + endif + +-alsaucm_SOURCES = usecase.c ++alsaucm_SOURCES = usecase.c dump.c + + AM_CPPFLAGS = \ + -Wall -I$(top_srcdir)/include +diff --git a/alsaucm/dump.c b/alsaucm/dump.c +new file mode 100644 +index 000000000000..ae0af2f1f108 +--- /dev/null ++++ b/alsaucm/dump.c +@@ -0,0 +1,403 @@ ++/* ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) 2019 Red Hat Inc. ++ * Authors: Jaroslav Kysela ++ */ ++ ++#include ++#include ++#include ++#include ++#include "usecase.h" ++#include "aconfig.h" ++#include "version.h" ++ ++struct renderer { ++ int (*init)(struct renderer *r); ++ void (*done)(struct renderer *r); ++ int (*verb_begin)(struct renderer *r, ++ const char *verb, ++ const char *comment); ++ int (*verb_end)(struct renderer *r); ++ int (*device_begin)(struct renderer *r, ++ const char *device, ++ const char *comment); ++ int (*device_end)(struct renderer *r); ++ int (*modifier_begin)(struct renderer *r, ++ const char *device, ++ const char *comment); ++ int (*modifier_end)(struct renderer *r); ++ int (*supported_begin)(struct renderer *r); ++ int (*supported_value)(struct renderer *r, const char *value, int last); ++ int (*supported_end)(struct renderer *r); ++ int (*conflict_begin)(struct renderer *r); ++ int (*conflict_value)(struct renderer *r, const char *value, int last); ++ int (*conflict_end)(struct renderer *r); ++ int (*value_begin)(struct renderer *r); ++ int (*value_end)(struct renderer *r); ++ int (*value)(struct renderer *r, const char *ident, const char *value); ++ void *opaque; ++}; ++ ++struct text { ++ char a[1]; ++}; ++ ++static char *tesc(const char *s, char *buf, size_t buf_len) ++{ ++ char *dst = buf; ++ char c = '\0'; ++ if (strchr(s, '"') || strchr(s, ' ') || strchr(s, '.')) { ++ *dst++ = c = '"'; ++ buf_len--; ++ } ++ while (*s && buf_len > 2) { ++ if (*s == '\"') { ++ if (buf_len > 3) { ++ *dst++ = '"'; ++ *dst++ = *s++; ++ buf_len -= 2; ++ continue; ++ } else { ++ break; ++ } ++ } ++ *dst++ = *s++; ++ } ++ if (c) ++ *dst++ = c; ++ *dst = '\0'; ++ return buf; ++} ++ ++#define ESC(s, esc) tesc((s), (esc), sizeof(esc)) ++ ++static int text_verb_start(struct renderer *r, const char *verb, const char *comment) ++{ ++ char buf1[128], buf2[128]; ++ printf("Verb.%s {\n", ESC(verb, buf1)); ++ if (comment && comment[0]) ++ printf("\tComment %s\n", ESC(comment, buf2)); ++ return 0; ++} ++ ++static int text_verb_end(struct renderer *r) ++{ ++ printf("}\n"); ++ return 0; ++} ++ ++static int text_2nd_level_begin(struct renderer *r, ++ const char *key, ++ const char *val, ++ const char *comment) ++{ ++ char buf1[128], buf2[128]; ++ printf("\t%s.%s {\n", key, ESC(val, buf1)); ++ if (comment && comment[0]) ++ printf("\t\tComment %s\n", ESC(comment, buf2)); ++ return 0; ++} ++ ++static int text_2nd_level_end(struct renderer *r) ++{ ++ printf("\t}\n"); ++ return 0; ++} ++ ++static int text_2nd_level(struct renderer *r, const char *txt) ++{ ++ printf("\t\t%s", txt); ++ return 0; ++} ++ ++static int text_3rd_level(struct renderer *r, const char *txt) ++{ ++ printf("\t\t\t%s", txt); ++ return 0; ++} ++ ++static int text_dev_start(struct renderer *r, const char *dev, const char *comment) ++{ ++ return text_2nd_level_begin(r, "Device", dev, comment); ++} ++ ++static int text_mod_start(struct renderer *r, const char *dev, const char *comment) ++{ ++ return text_2nd_level_begin(r, "Modifier", dev, comment); ++} ++ ++static int text_supcon_start(struct renderer *r, const char *key) ++{ ++ if (text_2nd_level(r, key)) ++ return 1; ++ printf(" [\n"); ++ return 0; ++} ++ ++static int text_supcon_value(struct renderer *r, const char *value, int last) ++{ ++ char buf[256]; ++ ESC(value, buf); ++ if (!last && strlen(buf) < sizeof(buf) - 2) ++ strcat(buf, ","); ++ if (text_3rd_level(r, buf)) ++ return 1; ++ printf("\n"); ++ return 0; ++} ++ ++static int text_supcon_end(struct renderer *r) ++{ ++ return text_2nd_level(r, "]\n"); ++} ++ ++static int text_sup_start(struct renderer *r) ++{ ++ return text_supcon_start(r, "SupportedDevices"); ++} ++ ++static int text_con_start(struct renderer *r) ++{ ++ return text_supcon_start(r, "ConflictingDevices"); ++} ++ ++static int text_value_begin(struct renderer *r) ++{ ++ return text_2nd_level(r, "Values [\n"); ++} ++ ++static int text_value_end(struct renderer *r) ++{ ++ return text_2nd_level(r, "]\n"); ++} ++ ++static int text_value(struct renderer *r, const char *ident, const char *value) ++{ ++ char buf1[256], buf2[256]; ++ int err; ++ ++ ESC(ident, buf1); ++ err = text_3rd_level(r, buf1); ++ if (err < 0) ++ return err; ++ ESC(value, buf2); ++ printf(" %s\n", buf2); ++ return 0; ++} ++ ++static struct renderer text_renderer = { ++ .verb_begin = text_verb_start, ++ .verb_end = text_verb_end, ++ .device_begin = text_dev_start, ++ .device_end = text_2nd_level_end, ++ .modifier_begin = text_mod_start, ++ .modifier_end = text_2nd_level_end, ++ .supported_begin = text_sup_start, ++ .supported_value = text_supcon_value, ++ .supported_end = text_supcon_end, ++ .conflict_begin = text_con_start, ++ .conflict_value = text_supcon_value, ++ .conflict_end = text_supcon_end, ++ .value_begin = text_value_begin, ++ .value_end = text_value_end, ++ .value = text_value, ++}; ++ ++static int render_devlist(struct context *context, ++ struct renderer *render, ++ const char *verb, ++ const char *device, ++ const char *list, ++ int (*begin)(struct renderer *), ++ int (*value)(struct renderer *, const char *value, int last), ++ int (*end)(struct renderer *)) ++{ ++ snd_use_case_mgr_t *uc_mgr = context->uc_mgr; ++ const char **dev_list; ++ char buf[256]; ++ int err = 0, j, dev_num; ++ ++ snprintf(buf, sizeof(buf), "%s/%s/%s", list, device, verb); ++ dev_num = snd_use_case_get_list(uc_mgr, buf, &dev_list); ++ if (dev_num < 0) { ++ fprintf(stderr, "%s: unable to get %s for verb '%s' for device '%s'\n", ++ context->command, list, verb, device); ++ return dev_num; ++ } ++ if (dev_num > 0) { ++ err = begin(render); ++ if (err < 0) ++ goto __err; ++ for (j = 0; j < dev_num; j++) { ++ err = value(render, dev_list[j], j + 1 == dev_num); ++ if (err < 0) ++ goto __err; ++ } ++ err = end(render); ++ } ++__err: ++ snd_use_case_free_list(dev_list, dev_num); ++ return err; ++} ++ ++static int render_values(struct context *context, ++ struct renderer *render, ++ const char *verb, ++ const char *device) ++{ ++ snd_use_case_mgr_t *uc_mgr = context->uc_mgr; ++ const char **list, *value; ++ char buf[256]; ++ int err = 0, j, num; ++ ++ snprintf(buf, sizeof(buf), "_identifiers/%s/%s", device, verb); ++ num = snd_use_case_get_list(uc_mgr, buf, &list); ++ if (num < 0) { ++ fprintf(stderr, "%s: unable to get _identifiers for verb '%s' for device '%s': %s\n", ++ context->command, verb, device, snd_strerror(num)); ++ return num; ++ } ++ if (num == 0) ++ goto __err; ++ if (render->value_begin) { ++ err = render->value_begin(render); ++ if (err < 0) ++ goto __err; ++ } ++ for (j = 0; j < num; j++) { ++ snprintf(buf, sizeof(buf), "%s/%s/%s", list[j], device, verb); ++ err = snd_use_case_get(uc_mgr, buf, &value); ++ if (err < 0) { ++ fprintf(stderr, "%s: unable to get value '%s' for verb '%s' for device '%s': %s\n", ++ context->command, list[j], verb, device, snd_strerror(err)); ++ goto __err; ++ } ++ err = render->value(render, list[j], value); ++ free((char *)value); ++ if (err < 0) ++ goto __err; ++ } ++ if (render->value_end) ++ err = render->value_end(render); ++__err: ++ snd_use_case_free_list(list, num); ++ return err; ++} ++ ++static int render_device(struct context *context, ++ struct renderer *render, ++ const char *verb, ++ const char *device) ++{ ++ int err; ++ ++ err = render_devlist(context, render, verb, device, ++ "_supporteddevs", ++ render->supported_begin, ++ render->supported_value, ++ render->supported_end); ++ if (err < 0) ++ return err; ++ err = render_devlist(context, render, verb, device, ++ "_conflictingdevs", ++ render->conflict_begin, ++ render->conflict_value, ++ render->conflict_end); ++ if (err < 0) ++ return err; ++ return render_values(context, render, verb, device); ++} ++ ++static void render(struct context *context, struct renderer *render) ++{ ++ snd_use_case_mgr_t *uc_mgr = context->uc_mgr; ++ int i, j, num, dev_num; ++ const char **list, **dev_list, *verb, *comment; ++ char buf[256]; ++ ++ num = snd_use_case_verb_list(uc_mgr, &list); ++ if (num < 0) { ++ fprintf(stderr, "%s: no verbs found\n", context->command); ++ return; ++ } ++ if (render->init && render->init(render)) ++ goto __end; ++ for (i = 0; i < num; i += 2) { ++ /* verb */ ++ verb = list[i + 0]; ++ comment = list[i + 1]; ++ if (render->verb_begin(render, verb, comment)) ++ break; ++ /* devices */ ++ snprintf(buf, sizeof(buf), "_devices/%s", verb); ++ dev_num = snd_use_case_get_list(uc_mgr, buf, &dev_list); ++ if (dev_num < 0) { ++ fprintf(stderr, "%s: unable to get devices for verb '%s'\n", ++ context->command, verb); ++ continue; ++ } ++ for (j = 0; j < dev_num; j += 2) { ++ render->device_begin(render, dev_list[j + 0], dev_list[j + 1]); ++ if (render_device(context, render, verb, dev_list[j + 0])) { ++ snd_use_case_free_list(dev_list, dev_num); ++ goto __end; ++ } ++ render->device_end(render); ++ } ++ snd_use_case_free_list(dev_list, dev_num); ++ /* modifiers */ ++ snprintf(buf, sizeof(buf), "_modifiers/%s", verb); ++ dev_num = snd_use_case_get_list(uc_mgr, buf, &dev_list); ++ if (dev_num < 0) { ++ fprintf(stderr, "%s: unable to get modifiers for verb '%s'\n", ++ context->command, verb); ++ continue; ++ } ++ for (j = 0; j < dev_num; j += 2) { ++ render->modifier_begin(render, dev_list[j + 0], dev_list[j + 1]); ++ render->modifier_end(render); ++ } ++ snd_use_case_free_list(dev_list, dev_num); ++ /* end */ ++ if (render->verb_end(render)) ++ break; ++ } ++ if (render->done) ++ render->done(render); ++__end: ++ snd_use_case_free_list(list, num); ++} ++ ++void dump(struct context *context, const char *format) ++{ ++ struct renderer r; ++ ++ r.opaque = NULL; ++ if (strcasecmp(format, "text") == 0 || ++ strcasecmp(format, "txt") == 0) { ++ struct text t; ++ memset(&t, 0, sizeof(t)); ++ r = text_renderer; ++ r.opaque = &t; ++ } ++ if (r.opaque != NULL) { ++ render(context, &r); ++ return; ++ } ++ fprintf(stderr, "%s: unknown dump format '%s'\n", ++ context->command, format); ++} +diff --git a/alsaucm/usecase.c b/alsaucm/usecase.c +index 8b1c8c7182a0..44fc92bebfcd 100644 +--- a/alsaucm/usecase.c ++++ b/alsaucm/usecase.c +@@ -38,24 +38,12 @@ + #include + #include + #include ++#include "usecase.h" + #include "aconfig.h" + #include "version.h" + + #define MAX_BUF 256 + +-struct context { +- snd_use_case_mgr_t *uc_mgr; +- const char *command; +- char *card; +- char **argv; +- int argc; +- int arga; +- char *batch; +- unsigned int interactive:1; +- unsigned int no_open:1; +- unsigned int do_exit:1; +-}; +- + enum uc_cmd { + /* management */ + OM_UNKNOWN = 0, +@@ -63,6 +51,7 @@ enum uc_cmd { + OM_RESET, + OM_RELOAD, + OM_LISTCARDS, ++ OM_DUMP, + OM_LIST2, + OM_LIST1, + +@@ -88,11 +77,13 @@ static struct cmd cmds[] = { + { OM_RESET, 0, 1, "reset" }, + { OM_RELOAD, 0, 1, "reload" }, + { OM_LISTCARDS, 0, 0, "listcards" }, ++ { OM_DUMP, 1, 1, "dump" }, + { OM_LIST1, 1, 1, "list1" }, + { OM_LIST2, 1, 1, "list" }, + { OM_SET, 2, 1, "set" }, + { OM_GET, 1, 1, "get" }, + { OM_GETI, 1, 1, "geti" }, ++ { OM_DUMP, 1, 1, "dump" }, + { OM_HELP, 0, 0, "help" }, + { OM_QUIT, 0, 0, "quit" }, + { OM_HELP, 0, 0, "h" }, +@@ -117,6 +108,7 @@ static void dump_help(struct context *context) + " reset reset sound card to default state\n" + " reload reload configuration\n" + " listcards list available cards\n" ++" dump FORMAT dump all config information (format: text)\n" + " list IDENTIFIER list command, for items with value + comment\n" + " list1 IDENTIFIER list command, for items without comments\n" + " get IDENTIFIER get string value\n" +@@ -185,7 +177,6 @@ static void my_exit(struct context *context, int exitcode) + snd_config_update_free_global(); + exit(exitcode); + } +- + static void do_initial_open(struct context *context) + { + int card, err; +@@ -288,6 +279,9 @@ static int do_one(struct context *context, struct cmd *cmd, char **argv) + } + snd_use_case_free_list(list, err); + break; ++ case OM_DUMP: ++ dump(context, argv[0]); ++ break; + case OM_LIST1: + case OM_LIST2: + switch (cmd->code) { +diff --git a/alsaucm/usecase.h b/alsaucm/usecase.h +new file mode 100644 +index 000000000000..a85716a652e2 +--- /dev/null ++++ b/alsaucm/usecase.h +@@ -0,0 +1,35 @@ ++/* ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#ifndef __USECASE_H ++#define __USECASE_H ++ ++struct context { ++ snd_use_case_mgr_t *uc_mgr; ++ const char *command; ++ char *card; ++ char **argv; ++ int argc; ++ int arga; ++ char *batch; ++ unsigned int interactive:1; ++ unsigned int no_open:1; ++ unsigned int do_exit:1; ++}; ++ ++void dump(struct context *context, const char *format); ++ ++#endif +-- +2.16.4 + diff --git a/0009-alsaucm-add-json-dump-command.patch b/0009-alsaucm-add-json-dump-command.patch new file mode 100644 index 0000000..cd065a6 --- /dev/null +++ b/0009-alsaucm-add-json-dump-command.patch @@ -0,0 +1,358 @@ +From 49716fa61e9ddc67476d40f9ea84f07fe0017748 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Sat, 30 Nov 2019 20:30:33 +0100 +Subject: [PATCH 09/26] alsaucm: add json dump command + +Signed-off-by: Jaroslav Kysela +--- + alsaucm/dump.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + alsaucm/usecase.c | 2 +- + 2 files changed, 249 insertions(+), 4 deletions(-) + +diff --git a/alsaucm/dump.c b/alsaucm/dump.c +index ae0af2f1f108..bc638f1588e9 100644 +--- a/alsaucm/dump.c ++++ b/alsaucm/dump.c +@@ -32,10 +32,14 @@ struct renderer { + const char *verb, + const char *comment); + int (*verb_end)(struct renderer *r); ++ int (*device_block_begin)(struct renderer *r); ++ int (*device_block_end)(struct renderer *r); + int (*device_begin)(struct renderer *r, + const char *device, + const char *comment); + int (*device_end)(struct renderer *r); ++ int (*modifier_block_begin)(struct renderer *r); ++ int (*modifier_block_end)(struct renderer *r); + int (*modifier_begin)(struct renderer *r, + const char *device, + const char *comment); +@@ -52,6 +56,10 @@ struct renderer { + void *opaque; + }; + ++/* ++ * Text renderer ++ */ ++ + struct text { + char a[1]; + }; +@@ -177,12 +185,12 @@ static int text_con_start(struct renderer *r) + + static int text_value_begin(struct renderer *r) + { +- return text_2nd_level(r, "Values [\n"); ++ return text_2nd_level(r, "Values {\n"); + } + + static int text_value_end(struct renderer *r) + { +- return text_2nd_level(r, "]\n"); ++ return text_2nd_level(r, "}\n"); + } + + static int text_value(struct renderer *r, const char *ident, const char *value) +@@ -217,6 +225,220 @@ static struct renderer text_renderer = { + .value = text_value, + }; + ++/* ++ * JSON renderer ++ */ ++ ++struct json { ++ int block[5]; ++}; ++ ++static char *jesc(const char *s, char *buf, size_t buf_len) ++{ ++ char *dst = buf; ++ char c = '"'; ++ *dst++ = c; ++ buf_len--; ++ while (*s && buf_len > 2) { ++ if (*s == '\"') { ++ if (buf_len > 3) { ++ *dst++ = '"'; ++ *dst++ = *s++; ++ buf_len -= 2; ++ continue; ++ } else { ++ break; ++ } ++ } ++ *dst++ = *s++; ++ } ++ *dst++ = c; ++ *dst = '\0'; ++ return buf; ++} ++ ++#define JESC(s, esc) jesc((s), (esc), sizeof(esc)) ++ ++static void json_block(struct renderer *r, int level, int last) ++{ ++ struct json *j = r->opaque; ++ printf((j->block[level] && !last) ? ",\n" : "\n"); ++ j->block[level] = last ? 0 : 1; ++} ++ ++static int json_init(struct renderer *r) ++{ ++ printf("{\n \"Verbs\": {"); ++ return 0; ++} ++ ++static void json_done(struct renderer *r) ++{ ++ json_block(r, 0, 1); ++ printf(" }\n}\n"); ++} ++ ++static int json_verb_start(struct renderer *r, const char *verb, const char *comment) ++{ ++ char buf[256]; ++ json_block(r, 0, 0); ++ printf(" %s: {", JESC(verb, buf)); ++ if (comment && comment[0]) { ++ json_block(r, 1, 0); ++ printf(" \"Comment\": %s", JESC(comment, buf)); ++ } ++ return 0; ++} ++ ++static int json_verb_end(struct renderer *r) ++{ ++ json_block(r, 1, 1); ++ printf(" }"); ++ return 0; ++} ++ ++static int json_2nd_level_block_end(struct renderer *r) ++{ ++ json_block(r, 2, 1); ++ printf(" }"); ++ return 0; ++} ++ ++static int json_2nd_level_begin(struct renderer *r, ++ const char *val, ++ const char *comment) ++{ ++ char buf[256]; ++ json_block(r, 2, 0); ++ printf(" %s: {", JESC(val, buf)); ++ if (comment && comment[0]) { ++ json_block(r, 3, 0); ++ printf(" \"Comment\": %s", JESC(comment, buf)); ++ } ++ return 0; ++} ++ ++static int json_2nd_level_end(struct renderer *r) ++{ ++ json_block(r, 3, 1); ++ printf(" }"); ++ return 0; ++} ++ ++static int json_2nd_level(struct renderer *r, const char *txt) ++{ ++ printf(" %s", txt); ++ return 0; ++} ++ ++static int json_3rd_level(struct renderer *r, const char *txt) ++{ ++ printf(" %s", txt); ++ return 0; ++} ++ ++static int json_dev_block_start(struct renderer *r) ++{ ++ json_block(r, 1, 0); ++ printf(" \"Devices\": {"); ++ return 0; ++} ++ ++static int json_mod_block_start(struct renderer *r) ++{ ++ json_block(r, 1, 0); ++ printf(" \"Modifiers\": {"); ++ return 0; ++} ++ ++static int json_supcon_start(struct renderer *r, const char *key) ++{ ++ json_block(r, 3, 0); ++ if (json_2nd_level(r, key)) ++ return 1; ++ printf(": ["); ++ return 0; ++} ++ ++static int json_supcon_value(struct renderer *r, const char *value, int last) ++{ ++ char buf[256]; ++ JESC(value, buf); ++ json_block(r, 4, 0); ++ return json_3rd_level(r, buf); ++} ++ ++static int json_supcon_end(struct renderer *r) ++{ ++ json_block(r, 4, 1); ++ return json_2nd_level(r, "]"); ++} ++ ++static int json_sup_start(struct renderer *r) ++{ ++ return json_supcon_start(r, "\"SupportedDevices\""); ++} ++ ++static int json_con_start(struct renderer *r) ++{ ++ return json_supcon_start(r, "\"ConflictingDevices\""); ++} ++ ++static int json_value_begin(struct renderer *r) ++{ ++ json_block(r, 3, 0); ++ return json_2nd_level(r, "\"Values\": {"); ++} ++ ++static int json_value_end(struct renderer *r) ++{ ++ json_block(r, 4, 1); ++ return json_2nd_level(r, "}"); ++} ++ ++static int json_value(struct renderer *r, const char *ident, const char *value) ++{ ++ char buf[256]; ++ int err; ++ ++ json_block(r, 4, 0); ++ JESC(ident, buf); ++ err = json_3rd_level(r, buf); ++ if (err < 0) ++ return err; ++ JESC(value, buf); ++ printf(": %s", buf); ++ return 0; ++} ++ ++static struct renderer json_renderer = { ++ .init = json_init, ++ .done = json_done, ++ .verb_begin = json_verb_start, ++ .verb_end = json_verb_end, ++ .device_block_begin = json_dev_block_start, ++ .device_block_end = json_2nd_level_block_end, ++ .device_begin = json_2nd_level_begin, ++ .device_end = json_2nd_level_end, ++ .modifier_block_begin = json_mod_block_start, ++ .modifier_block_end = json_2nd_level_block_end, ++ .modifier_begin = json_2nd_level_begin, ++ .modifier_end = json_2nd_level_end, ++ .supported_begin = json_sup_start, ++ .supported_value = json_supcon_value, ++ .supported_end = json_supcon_end, ++ .conflict_begin = json_con_start, ++ .conflict_value = json_supcon_value, ++ .conflict_end = json_supcon_end, ++ .value_begin = json_value_begin, ++ .value_end = json_value_end, ++ .value = json_value, ++}; ++ ++/* ++ * universal dump functions ++ */ ++ + static int render_devlist(struct context *context, + struct renderer *render, + const char *verb, +@@ -350,6 +572,12 @@ static void render(struct context *context, struct renderer *render) + context->command, verb); + continue; + } ++ if (dev_num == 0) ++ goto __mods; ++ if (render->device_block_begin && render->device_block_begin(render)) { ++ snd_use_case_free_list(dev_list, dev_num); ++ goto __end; ++ } + for (j = 0; j < dev_num; j += 2) { + render->device_begin(render, dev_list[j + 0], dev_list[j + 1]); + if (render_device(context, render, verb, dev_list[j + 0])) { +@@ -359,6 +587,9 @@ static void render(struct context *context, struct renderer *render) + render->device_end(render); + } + snd_use_case_free_list(dev_list, dev_num); ++ if (render->device_block_end && render->device_block_end(render)) ++ goto __end; ++__mods: + /* modifiers */ + snprintf(buf, sizeof(buf), "_modifiers/%s", verb); + dev_num = snd_use_case_get_list(uc_mgr, buf, &dev_list); +@@ -367,11 +598,20 @@ static void render(struct context *context, struct renderer *render) + context->command, verb); + continue; + } ++ if (dev_num == 0) ++ goto __verb_end; ++ if (render->modifier_block_begin && render->modifier_block_begin(render)) { ++ snd_use_case_free_list(dev_list, dev_num); ++ goto __end; ++ } + for (j = 0; j < dev_num; j += 2) { + render->modifier_begin(render, dev_list[j + 0], dev_list[j + 1]); + render->modifier_end(render); + } + snd_use_case_free_list(dev_list, dev_num); ++ if (render->modifier_block_end && render->modifier_block_end(render)) ++ goto __end; ++__verb_end: + /* end */ + if (render->verb_end(render)) + break; +@@ -385,14 +625,19 @@ __end: + void dump(struct context *context, const char *format) + { + struct renderer r; ++ struct text t; ++ struct json j; + + r.opaque = NULL; + if (strcasecmp(format, "text") == 0 || + strcasecmp(format, "txt") == 0) { +- struct text t; + memset(&t, 0, sizeof(t)); + r = text_renderer; + r.opaque = &t; ++ } else if (strcasecmp(format, "json") == 0) { ++ memset(&j, 0, sizeof(j)); ++ r = json_renderer; ++ r.opaque = &j; + } + if (r.opaque != NULL) { + render(context, &r); +diff --git a/alsaucm/usecase.c b/alsaucm/usecase.c +index 44fc92bebfcd..1ed91ea56863 100644 +--- a/alsaucm/usecase.c ++++ b/alsaucm/usecase.c +@@ -108,7 +108,7 @@ static void dump_help(struct context *context) + " reset reset sound card to default state\n" + " reload reload configuration\n" + " listcards list available cards\n" +-" dump FORMAT dump all config information (format: text)\n" ++" dump FORMAT dump all config information (format: text,json)\n" + " list IDENTIFIER list command, for items with value + comment\n" + " list1 IDENTIFIER list command, for items without comments\n" + " get IDENTIFIER get string value\n" +-- +2.16.4 + diff --git a/0010-alsaucm-dump-fix-the-prefixed.patch b/0010-alsaucm-dump-fix-the-prefixed.patch new file mode 100644 index 0000000..cabf10f --- /dev/null +++ b/0010-alsaucm-dump-fix-the-prefixed.patch @@ -0,0 +1,41 @@ +From 160b47e27c787880f1581a0f2e70138f6b24c41b Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Sat, 30 Nov 2019 20:38:17 +0100 +Subject: [PATCH 10/26] alsaucm: dump - fix the prefixed " + +Signed-off-by: Jaroslav Kysela +--- + alsaucm/dump.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/alsaucm/dump.c b/alsaucm/dump.c +index bc638f1588e9..7a90c828fe1f 100644 +--- a/alsaucm/dump.c ++++ b/alsaucm/dump.c +@@ -73,9 +73,9 @@ static char *tesc(const char *s, char *buf, size_t buf_len) + buf_len--; + } + while (*s && buf_len > 2) { +- if (*s == '\"') { ++ if (*s == '"') { + if (buf_len > 3) { +- *dst++ = '"'; ++ *dst++ = '\\'; + *dst++ = *s++; + buf_len -= 2; + continue; +@@ -240,9 +240,9 @@ static char *jesc(const char *s, char *buf, size_t buf_len) + *dst++ = c; + buf_len--; + while (*s && buf_len > 2) { +- if (*s == '\"') { ++ if (*s == '"') { + if (buf_len > 3) { +- *dst++ = '"'; ++ *dst++ = '\\'; + *dst++ = *s++; + buf_len -= 2; + continue; +-- +2.16.4 + diff --git a/0011-alsactl-fix-sched-idle-set-it-really-to-SCHED_IDLE.patch b/0011-alsactl-fix-sched-idle-set-it-really-to-SCHED_IDLE.patch new file mode 100644 index 0000000..0ec27c3 --- /dev/null +++ b/0011-alsactl-fix-sched-idle-set-it-really-to-SCHED_IDLE.patch @@ -0,0 +1,41 @@ +From 34e373d0b12d96353c49c3dcd73ec52eee11484a Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Tue, 3 Dec 2019 13:53:25 +0100 +Subject: [PATCH 11/26] alsactl: fix --sched-idle (set it really to SCHED_IDLE) + +Reported-by: tommy +Signed-off-by: Jaroslav Kysela +--- + alsactl/Makefile.am | 2 ++ + alsactl/alsactl.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am +index aaaf74ee1e18..e9ab2eb28bbf 100644 +--- a/alsactl/Makefile.am ++++ b/alsactl/Makefile.am +@@ -7,6 +7,8 @@ man_MANS += alsactl_init.7 + endif + EXTRA_DIST=alsactl.1 alsactl_init.xml + ++AM_CFLAGS = -D_GNU_SOURCE ++ + alsactl_SOURCES=alsactl.c state.c lock.c utils.c init_parse.c daemon.c \ + monitor.c + +diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c +index 94cae239d1f2..dfb1db7f4a83 100644 +--- a/alsactl/alsactl.c ++++ b/alsactl/alsactl.c +@@ -161,7 +161,7 @@ static void do_nice(int use_nice, int sched_idle) + if (sched_idle) { + if (sched_getparam(0, &sched_param) >= 0) { + sched_param.sched_priority = 0; +- if (!sched_setscheduler(0, SCHED_RR, &sched_param)) ++ if (!sched_setscheduler(0, SCHED_IDLE, &sched_param)) + error("sched_setparam failed: %s", strerror(errno)); + } else { + error("sched_getparam failed: %s", strerror(errno)); +-- +2.16.4 + diff --git a/0012-configure-Fix-linking-of-alsatplg-with-the-older-lib.patch b/0012-configure-Fix-linking-of-alsatplg-with-the-older-lib.patch new file mode 100644 index 0000000..63cef44 --- /dev/null +++ b/0012-configure-Fix-linking-of-alsatplg-with-the-older-lib.patch @@ -0,0 +1,30 @@ +From f77a269370af917585df59d8c21c89bca07b5b73 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Tue, 3 Dec 2019 20:51:56 +0100 +Subject: [PATCH 12/26] configure: Fix linking of alsatplg with the older libs + +BugLink: https://github.com/alsa-project/alsa-utils/issues/33 +Signed-off-by: Jaroslav Kysela +--- + configure.ac | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/configure.ac b/configure.ac +index a4a2dd4480f7..4bee49be81ba 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -70,6 +70,11 @@ AM_CONDITIONAL(HAVE_TOPOLOGY, test "$have_topology" = "yes") + AM_CONDITIONAL(HAVE_SAMPLERATE, test "$have_samplerate" = "yes") + AM_CONDITIONAL(HAVE_FFADO, test "$have_ffado" = "yes") + ++# old libasound with the topology routines in the main library ++if test "x$have_topology" = "xyes" -a "x$ALSA_TOPOLOGY_LIBS" = "x"; then ++ ALSA_TOPOLOGY_LIBS="$ALSA_LIBS" ++fi ++ + dnl Use tinyalsa + alsabat_backend_tiny= + AC_ARG_ENABLE(alsabat_backend_tiny, +-- +2.16.4 + diff --git a/0013-alsatplg-add-n-normalize-option.patch b/0013-alsatplg-add-n-normalize-option.patch new file mode 100644 index 0000000..c9b816a --- /dev/null +++ b/0013-alsatplg-add-n-normalize-option.patch @@ -0,0 +1,226 @@ +From 08d2341a176248a346efbdaa6d8878f3ebd627da Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 12 Dec 2019 19:00:42 +0100 +Subject: [PATCH 13/26] alsatplg: add -n,--normalize option + +This function loads and parses the topology file and +saves back the structured output in the alsa-lib's format +without comments. + +Signed-off-by: Jaroslav Kysela +--- + topology/topology.c | 165 +++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 145 insertions(+), 20 deletions(-) + +diff --git a/topology/topology.c b/topology/topology.c +index b72e341fb5fd..a6ebafab161b 100644 +--- a/topology/topology.c ++++ b/topology/topology.c +@@ -43,23 +43,154 @@ _("Usage: %s [OPTIONS]...\n" + "\n" + "-h, --help help\n" + "-c, --compile=FILE compile file\n" ++"-n, --normalize=FILE normalize file\n" + "-v, --verbose=LEVEL set verbosity level (0...1)\n" + "-o, --output=FILE set output file\n" + ), name); + } + +-int main(int argc, char *argv[]) ++static int _compar(const void *a, const void *b) ++{ ++ const snd_config_t *c1 = *(snd_config_t **)a; ++ const snd_config_t *c2 = *(snd_config_t **)b; ++ const char *id1, *id2; ++ if (snd_config_get_id(c1, &id1)) return 0; ++ if (snd_config_get_id(c2, &id2)) return 0; ++ return strcmp(id1, id2); ++} ++ ++static snd_config_t *normalize_config(const char *id, snd_config_t *src) ++{ ++ snd_config_t *dst, **a; ++ snd_config_iterator_t i, next; ++ int index, count; ++ ++ if (snd_config_get_type(src) != SND_CONFIG_TYPE_COMPOUND) { ++ if (snd_config_copy(&dst, src) >= 0) ++ return dst; ++ return NULL; ++ } ++ if (snd_config_make_compound(&dst, id, 0)) ++ return NULL; ++ count = 0; ++ snd_config_for_each(i, next, src) ++ count++; ++ a = malloc(sizeof(dst) * count); ++ if (a == NULL) ++ return NULL; ++ index = 0; ++ snd_config_for_each(i, next, src) { ++ snd_config_t *s = snd_config_iterator_entry(i); ++ a[index++] = s; ++ } ++ qsort(a, count, sizeof(a[0]), _compar); ++ for (index = 0; index < count; index++) { ++ snd_config_t *s = a[index]; ++ const char *id2; ++ if (snd_config_get_id(s, &id2)) { ++ snd_config_delete(dst); ++ return NULL; ++ } ++ s = normalize_config(id2, s); ++ if (s == NULL || snd_config_add(dst, s)) { ++ snd_config_delete(dst); ++ return NULL; ++ } ++ } ++ return dst; ++} ++ ++static int compile(const char *source_file, const char *output_file, int verbose) + { + snd_tplg_t *snd_tplg; +- static const char short_options[] = "hc:v:o:"; ++ int err; ++ ++ snd_tplg = snd_tplg_new(); ++ if (snd_tplg == NULL) { ++ fprintf(stderr, _("failed to create new topology context\n")); ++ return 1; ++ } ++ ++ snd_tplg_verbose(snd_tplg, verbose); ++ ++ err = snd_tplg_build_file(snd_tplg, source_file, output_file); ++ if (err < 0) { ++ fprintf(stderr, _("failed to compile context %s\n"), source_file); ++ snd_tplg_free(snd_tplg); ++ unlink(output_file); ++ return 1; ++ } ++ ++ snd_tplg_free(snd_tplg); ++ return 1; ++} ++ ++static int normalize(const char *source_file, const char *output_file) ++{ ++ snd_input_t *input; ++ snd_output_t *output; ++ snd_config_t *top, *norm; ++ int err; ++ ++ err = snd_input_stdio_open(&input, source_file, "r"); ++ if (err < 0) { ++ fprintf(stderr, "Unable to open source file '%s': %s\n", source_file, snd_strerror(-err)); ++ return 0; ++ } ++ ++ err = snd_config_top(&top); ++ if (err < 0) { ++ snd_input_close(input); ++ return 1; ++ } ++ ++ err = snd_config_load(top, input); ++ snd_input_close(input); ++ if (err < 0) { ++ snd_config_delete(top); ++ fprintf(stderr, "Unable to parse source file '%s': %s\n", source_file, snd_strerror(-err)); ++ snd_config_delete(top); ++ return 1; ++ } ++ ++ err = snd_output_stdio_open(&output, output_file, "w+"); ++ if (err < 0) { ++ fprintf(stderr, "Unable to open output file '%s': %s\n", output_file, snd_strerror(-err)); ++ snd_config_delete(top); ++ return 1; ++ } ++ ++ norm = normalize_config(NULL, top); ++ if (norm == NULL) { ++ fprintf(stderr, "Unable to normalize configuration (out of memory?)\n"); ++ snd_output_close(output); ++ snd_config_delete(top); ++ return 1; ++ } ++ ++ err = snd_config_save(norm, output); ++ snd_output_close(output); ++ snd_config_delete(top); ++ if (err < 0) { ++ fprintf(stderr, "Unable to save normalized contents: %s\n", snd_strerror(-err)); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ static const char short_options[] = "hc:n:v:o:"; + static const struct option long_options[] = { + {"help", 0, NULL, 'h'}, + {"verbose", 1, NULL, 'v'}, + {"compile", 1, NULL, 'c'}, ++ {"normalize", 1, NULL, 'n'}, + {"output", 1, NULL, 'o'}, + {0, 0, 0, 0}, + }; +- char *source_file = NULL, *output_file = NULL; ++ char *source_file = NULL, *normalize_file = NULL, *output_file = NULL; + int c, err, verbose = 0, option_index; + + #ifdef ENABLE_NLS +@@ -81,6 +212,9 @@ int main(int argc, char *argv[]) + case 'c': + source_file = optarg; + break; ++ case 'n': ++ normalize_file = optarg; ++ break; + case 'o': + output_file = optarg; + break; +@@ -90,28 +224,19 @@ int main(int argc, char *argv[]) + } + } + +- if (source_file == NULL || output_file == NULL) { +- usage(argv[0]); +- return 1; +- } +- +- snd_tplg = snd_tplg_new(); +- if (snd_tplg == NULL) { +- fprintf(stderr, _("failed to create new topology context\n")); ++ if (source_file && normalize_file) { ++ fprintf(stderr, "Cannot normalize and compile at a time!\n"); + return 1; + } + +- snd_tplg_verbose(snd_tplg, verbose); +- +- err = snd_tplg_build_file(snd_tplg, source_file, output_file); +- if (err < 0) { +- fprintf(stderr, _("failed to compile context %s\n"), source_file); +- snd_tplg_free(snd_tplg); +- unlink(output_file); ++ if ((source_file == NULL && normalize_file == NULL) || output_file == NULL) { ++ usage(argv[0]); + return 1; + } + +- snd_tplg_free(snd_tplg); ++ if (source_file) ++ err = compile(source_file, output_file, verbose); ++ else ++ err = normalize(normalize_file, output_file); + return 0; + } +- +-- +2.16.4 + diff --git a/0014-alsatplg-add-s-sort-and-fix-memory-leaks.patch b/0014-alsatplg-add-s-sort-and-fix-memory-leaks.patch new file mode 100644 index 0000000..bb886c1 --- /dev/null +++ b/0014-alsatplg-add-s-sort-and-fix-memory-leaks.patch @@ -0,0 +1,141 @@ +From 2656d4bec8fab8b4b9046d3b8c9c255dc2166014 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 12 Dec 2019 19:18:28 +0100 +Subject: [PATCH 14/26] alsatplg: add -s,--sort and fix memory leaks + +Signed-off-by: Jaroslav Kysela +--- + topology/topology.c | 34 ++++++++++++++++++++++++---------- + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/topology/topology.c b/topology/topology.c +index a6ebafab161b..c12be7806929 100644 +--- a/topology/topology.c ++++ b/topology/topology.c +@@ -46,6 +46,7 @@ _("Usage: %s [OPTIONS]...\n" + "-n, --normalize=FILE normalize file\n" + "-v, --verbose=LEVEL set verbosity level (0...1)\n" + "-o, --output=FILE set output file\n" ++"-s, --sort sort the identifiers in the normalized output\n" + ), name); + } + +@@ -59,7 +60,7 @@ static int _compar(const void *a, const void *b) + return strcmp(id1, id2); + } + +-static snd_config_t *normalize_config(const char *id, snd_config_t *src) ++static snd_config_t *normalize_config(const char *id, snd_config_t *src, int sort) + { + snd_config_t *dst, **a; + snd_config_iterator_t i, next; +@@ -70,8 +71,6 @@ static snd_config_t *normalize_config(const char *id, snd_config_t *src) + return dst; + return NULL; + } +- if (snd_config_make_compound(&dst, id, 0)) +- return NULL; + count = 0; + snd_config_for_each(i, next, src) + count++; +@@ -83,20 +82,28 @@ static snd_config_t *normalize_config(const char *id, snd_config_t *src) + snd_config_t *s = snd_config_iterator_entry(i); + a[index++] = s; + } +- qsort(a, count, sizeof(a[0]), _compar); ++ if (sort) ++ qsort(a, count, sizeof(a[0]), _compar); ++ if (snd_config_make_compound(&dst, id, count == 1)) { ++ free(a); ++ return NULL; ++ } + for (index = 0; index < count; index++) { + snd_config_t *s = a[index]; + const char *id2; + if (snd_config_get_id(s, &id2)) { + snd_config_delete(dst); ++ free(a); + return NULL; + } +- s = normalize_config(id2, s); ++ s = normalize_config(id2, s, sort); + if (s == NULL || snd_config_add(dst, s)) { + snd_config_delete(dst); ++ free(a); + return NULL; + } + } ++ free(a); + return dst; + } + +@@ -125,7 +132,7 @@ static int compile(const char *source_file, const char *output_file, int verbose + return 1; + } + +-static int normalize(const char *source_file, const char *output_file) ++static int normalize(const char *source_file, const char *output_file, int sort) + { + snd_input_t *input; + snd_output_t *output; +@@ -160,7 +167,7 @@ static int normalize(const char *source_file, const char *output_file) + return 1; + } + +- norm = normalize_config(NULL, top); ++ norm = normalize_config(NULL, top, sort); + if (norm == NULL) { + fprintf(stderr, "Unable to normalize configuration (out of memory?)\n"); + snd_output_close(output); +@@ -170,6 +177,7 @@ static int normalize(const char *source_file, const char *output_file) + + err = snd_config_save(norm, output); + snd_output_close(output); ++ snd_config_delete(norm); + snd_config_delete(top); + if (err < 0) { + fprintf(stderr, "Unable to save normalized contents: %s\n", snd_strerror(-err)); +@@ -181,17 +189,18 @@ static int normalize(const char *source_file, const char *output_file) + + int main(int argc, char *argv[]) + { +- static const char short_options[] = "hc:n:v:o:"; ++ static const char short_options[] = "hc:n:v:o:s"; + static const struct option long_options[] = { + {"help", 0, NULL, 'h'}, + {"verbose", 1, NULL, 'v'}, + {"compile", 1, NULL, 'c'}, + {"normalize", 1, NULL, 'n'}, + {"output", 1, NULL, 'o'}, ++ {"sort", 0, NULL, 's'}, + {0, 0, 0, 0}, + }; + char *source_file = NULL, *normalize_file = NULL, *output_file = NULL; +- int c, err, verbose = 0, option_index; ++ int c, err, verbose = 0, sort = 0, option_index; + + #ifdef ENABLE_NLS + setlocale(LC_ALL, ""); +@@ -218,6 +227,9 @@ int main(int argc, char *argv[]) + case 'o': + output_file = optarg; + break; ++ case 's': ++ sort = 1; ++ break; + default: + fprintf(stderr, _("Try `%s --help' for more information.\n"), argv[0]); + return 1; +@@ -237,6 +249,8 @@ int main(int argc, char *argv[]) + if (source_file) + err = compile(source_file, output_file, verbose); + else +- err = normalize(normalize_file, output_file); ++ err = normalize(normalize_file, output_file, sort); ++ ++ snd_output_close(log); + return 0; + } +-- +2.16.4 + diff --git a/0015-alsatplg-fix-another-small-leak-in-normalize_config.patch b/0015-alsatplg-fix-another-small-leak-in-normalize_config.patch new file mode 100644 index 0000000..5ee19d5 --- /dev/null +++ b/0015-alsatplg-fix-another-small-leak-in-normalize_config.patch @@ -0,0 +1,26 @@ +From 10db898d9b97f0a8d3093405ad5b4aa4ed53801d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 13 Dec 2019 10:44:36 +0100 +Subject: [PATCH 15/26] alsatplg: fix another small leak in normalize_config() + +Signed-off-by: Jaroslav Kysela +--- + topology/topology.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/topology/topology.c b/topology/topology.c +index c12be7806929..bc5797c5f14f 100644 +--- a/topology/topology.c ++++ b/topology/topology.c +@@ -98,6 +98,8 @@ static snd_config_t *normalize_config(const char *id, snd_config_t *src, int sor + } + s = normalize_config(id2, s, sort); + if (s == NULL || snd_config_add(dst, s)) { ++ if (s) ++ snd_config_delete(s); + snd_config_delete(dst); + free(a); + return NULL; +-- +2.16.4 + diff --git a/0016-alsa-info.sh-Consolidate-PCI-device-output.patch b/0016-alsa-info.sh-Consolidate-PCI-device-output.patch new file mode 100644 index 0000000..e0baf85 --- /dev/null +++ b/0016-alsa-info.sh-Consolidate-PCI-device-output.patch @@ -0,0 +1,45 @@ +From 11e083d81c330539f0f170bb238a17b1c2e0cb4d Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:01 -0500 +Subject: [PATCH 16/26] alsa-info.sh: Consolidate PCI device output + +Include numeric IDs and subsystem info in the PCI device output, +without placing them in a separate section. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index cf7ad8979a6f..8fc69972f9f3 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -455,7 +455,9 @@ fi + cat /proc/asound/modules 2>/dev/null | awk '{ print $2 }' > $TEMPDIR/alsamodules.tmp + cat /proc/asound/cards > $TEMPDIR/alsacards.tmp + if [[ ! -z "$LSPCI" ]]; then +- lspci | grep -i "multi\|audio">$TEMPDIR/lspci.tmp ++ for class in 0401 0402 0403; do ++ lspci -vvnn -d "::$class" | sed -n '/^[^\t]/,+1p' ++ done > $TEMPDIR/lspci.tmp + fi + + #Check for HDA-Intel cards codec#* +@@ -585,12 +587,6 @@ echo "" >> $FILE + cat $TEMPDIR/lspci.tmp >> $FILE + echo "" >> $FILE + echo "" >> $FILE +-echo "!!Advanced information - PCI Vendor/Device/Subsystem ID's" >> $FILE +-echo "!!-------------------------------------------------------" >> $FILE +-echo "" >> $FILE +-lspci -vvn |grep -A1 040[1-3] >> $FILE +-echo "" >> $FILE +-echo "" >> $FILE + fi + + if [ "$SNDOPTIONS" ] +-- +2.16.4 + diff --git a/0017-alsa-info.sh-Read-from-proc-modules-and-sort-the-res.patch b/0017-alsa-info.sh-Read-from-proc-modules-and-sort-the-res.patch new file mode 100644 index 0000000..47b276f --- /dev/null +++ b/0017-alsa-info.sh-Read-from-proc-modules-and-sort-the-res.patch @@ -0,0 +1,69 @@ +From 86b1f80e24b68ce8153874e6ac851fa2b90c43b5 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:02 -0500 +Subject: [PATCH 17/26] alsa-info.sh: Read from /proc/modules and sort the + result + +Sorting the list of loaded modules makes it much easier to compare +two alsa-info.txt files, even if they are both from the same system +(since the order actually changes after each reboot). + +lsmod just formats the contents of /proc/modules. After this script +calls lsmod, it strips everything but module names from the output. +This same result can be obtained just as easily by reading directly +from /proc/modules; then there is no need to remove the header line +printed by lsmod before sorting the output. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 8fc69972f9f3..ed1d9e248405 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -35,7 +35,7 @@ BGTITLE="ALSA-Info v $SCRIPT_VERSION" + PASTEBINKEY="C9cRIO8m/9y8Cs0nVs0FraRx7U0pHsuc" + + WGET=$(which wget 2>/dev/null | sed 's|^[^/]*||' 2>/dev/null) +-REQUIRES="mktemp grep pgrep whereis ping awk date uname cat dmesg amixer alsactl" ++REQUIRES="mktemp grep pgrep whereis ping awk date uname cat sort dmesg amixer alsactl" + + # + # Define some simple functions +@@ -131,11 +131,11 @@ withaplay() { + echo "" >> $FILE + } + +-withlsmod() { ++withmodules() { + echo "!!All Loaded Modules" >> $FILE + echo "!!------------------" >> $FILE + echo "" >> $FILE +- lsmod | awk '{print $1}' >> $FILE ++ awk '{print $1}' < /proc/modules | sort >> $FILE + echo "" >> $FILE + echo "" >> $FILE + } +@@ -254,7 +254,7 @@ withall() { + withaplay + withamixer + withalsactl +- withlsmod ++ withmodules + withsysfs + withdmesg + WITHALL="no" +@@ -366,7 +366,6 @@ information about your ALSA installation and sound related hardware. + + dmesg + lspci +- lsmod + aplay + amixer + alsactl +-- +2.16.4 + diff --git a/0018-alsa-info.sh-Simplify-iteration-over-cards-when-call.patch b/0018-alsa-info.sh-Simplify-iteration-over-cards-when-call.patch new file mode 100644 index 0000000..8811159 --- /dev/null +++ b/0018-alsa-info.sh-Simplify-iteration-over-cards-when-call.patch @@ -0,0 +1,40 @@ +From 068dd55717d4e020849e4dd12610d16968cf49be Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:03 -0500 +Subject: [PATCH 18/26] alsa-info.sh: Simplify iteration over cards when + calling amixer + +Read card names directly from individual procfs files, and pass them +to amixer using the '-c' option. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index ed1d9e248405..e1067d42f9f8 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -144,12 +144,12 @@ withamixer() { + echo "!!Amixer output" >> $FILE + echo "!!-------------" >> $FILE + echo "" >> $FILE +- for i in $(grep "]: " /proc/asound/cards | awk -F ' ' '{ print $1 }') ; do +- CARD_NAME=$(grep "^ *$i " $TEMPDIR/alsacards.tmp | awk '{ print $2 }') +- echo "!!-------Mixer controls for card $i $CARD_NAME]" >> $FILE ++ for f in /proc/asound/card*/id; do ++ [ -f "$f" ] && read -r CARD_NAME < "$f" || continue ++ echo "!!-------Mixer controls for card $CARD_NAME" >> $FILE + echo "" >>$FILE +- amixer -c$i info >> $FILE 2>&1 +- amixer -c$i >> $FILE 2>&1 ++ amixer -c "$CARD_NAME" info >> $FILE 2>&1 ++ amixer -c "$CARD_NAME" >> $FILE 2>&1 + echo "" >> $FILE + done + echo "" >> $FILE +-- +2.16.4 + diff --git a/0019-alsa-info.sh-Use-existing-function-to-print-ALSA-con.patch b/0019-alsa-info.sh-Use-existing-function-to-print-ALSA-con.patch new file mode 100644 index 0000000..e633a98 --- /dev/null +++ b/0019-alsa-info.sh-Use-existing-function-to-print-ALSA-con.patch @@ -0,0 +1,54 @@ +From de5ce14163dbc1337075de1f5d632fd49865a338 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:04 -0500 +Subject: [PATCH 19/26] alsa-info.sh: Use existing function to print ALSA + configuration files + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 27 +-------------------------- + 1 file changed, 1 insertion(+), 26 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index e1067d42f9f8..bf353deceb7d 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -710,33 +710,8 @@ if [ -n "$1" ]; then + WITHALL="no" + ;; + --with-configs) ++ withconfigs + WITHALL="no" +- if [[ -e $HOME/.asoundrc ]] || [[ -e /etc/asound.conf ]] +- then +- echo "!!ALSA configuration files" >> $FILE +- echo "!!------------------------" >> $FILE +- echo "" >> $FILE +- +- #Check for ~/.asoundrc +- if [[ -e $HOME/.asoundrc ]] +- then +- echo "!!User specific config file ($HOME/.asoundrc)" >> $FILE +- echo "" >> $FILE +- cat $HOME/.asoundrc >> $FILE +- echo "" >> $FILE +- echo "" >> $FILE +- fi +- +- #Check for /etc/asound.conf +- if [[ -e /etc/asound.conf ]] +- then +- echo "!!System wide config file (/etc/asound.conf)" >> $FILE +- echo "" >> $FILE +- cat /etc/asound.conf >> $FILE +- echo "" >> $FILE +- echo "" >> $FILE +- fi +- fi + ;; + --stdout) + UPLOAD="no" +-- +2.16.4 + diff --git a/0020-alsa-info.sh-Exit-script-after-writing-information-t.patch b/0020-alsa-info.sh-Exit-script-after-writing-information-t.patch new file mode 100644 index 0000000..6f8eb08 --- /dev/null +++ b/0020-alsa-info.sh-Exit-script-after-writing-information-t.patch @@ -0,0 +1,67 @@ +From e9e3c3a27d4faad0000a10386da471227b0644d8 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:05 -0500 +Subject: [PATCH 20/26] alsa-info.sh: Exit script after writing information to + stdout + +The '--stdout' option is mutually exclusive with uploading the file. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index bf353deceb7d..372d7ae3d692 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -349,9 +349,7 @@ case "$1" in + ;; + --stdout) + DIALOG="" +- UPLOAD="no" + WELCOME="no" +- TOSTDOUT="yes" + ;; + esac + done +@@ -720,6 +718,7 @@ if [ -n "$1" ]; then + fi + cat $FILE + rm $FILE ++ exit + ;; + --about) + echo "Written/Tested by the following users of #alsa on irc.freenode.net:" +@@ -793,10 +792,8 @@ fi + + if [ "$UPLOAD" = "no" ]; then + +- if [ -z "$TOSTDOUT" ]; then +- mv -f $FILE $NFILE || exit 1 +- KEEP_OUTPUT="yes" +- fi ++ mv -f $FILE $NFILE || exit 1 ++ KEEP_OUTPUT="yes" + + if [[ -n $DIALOG ]] + then +@@ -815,11 +812,9 @@ if [ "$UPLOAD" = "no" ]; then + echo "Your ALSA information is in $NFILE" + echo "" + else +- if [ -z "$TOSTDOUT" ]; then +- echo "" +- echo "Your ALSA information is in $NFILE" +- echo "" +- fi ++ echo "" ++ echo "Your ALSA information is in $NFILE" ++ echo "" + fi + fi + +-- +2.16.4 + diff --git a/0021-alsa-info.sh-Replace-gauge-with-infobox-for-upload-d.patch b/0021-alsa-info.sh-Replace-gauge-with-infobox-for-upload-d.patch new file mode 100644 index 0000000..94ca2ea --- /dev/null +++ b/0021-alsa-info.sh-Replace-gauge-with-infobox-for-upload-d.patch @@ -0,0 +1,46 @@ +From d928f7667cfead36b33f38ad7668ca96c6045d4e Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:06 -0500 +Subject: [PATCH 21/26] alsa-info.sh: Replace gauge with infobox for upload + dialog + +The gauge did not actually show the upload progress; in fact, the +dialog did not even appear until after the upload was completed. + +Use an infobox instead, which will be displayed while wget runs. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 372d7ae3d692..a02864d0a69d 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -830,19 +830,11 @@ if [[ -n $DIALOG ]] + then + + if [[ -z $PASTEBIN ]]; then ++ dialog --backtitle "$BGTITLE" --infobox "Uploading information to www.alsa-project.org ..." 6 70 + wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://www.alsa-project.org/cardinfo-db/" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" +- { for i in 10 20 30 40 50 60 70 80 90; do +- echo $i +- sleep 0.2 +- done +- echo; } |dialog --backtitle "$BGTITLE" --guage "Uploading information to www.alsa-project.org ..." 6 70 0 + else ++ dialog --backtitle "$BGTITLE" --infobox "Uploading information to www.pastebin.ca ..." 6 70 + wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY&encrypt=t&encryptpw=blahblah" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" +- { for i in 10 20 30 40 50 60 70 80 90; do +- echo $i +- sleep 0.2 +- done +- echo; } |dialog --backtitle "$BGTITLE" --guage "Uploading information to www.pastebin.ca ..." 6 70 0 + fi + + dialog --backtitle "$BGTITLE" --title "Information uploaded" --yesno "Would you like to see the uploaded information?" 5 100 +-- +2.16.4 + diff --git a/0022-alsa-info.sh-Remove-progress-spinner-during-upload-w.patch b/0022-alsa-info.sh-Remove-progress-spinner-during-upload-w.patch new file mode 100644 index 0000000..d52b1f1 --- /dev/null +++ b/0022-alsa-info.sh-Remove-progress-spinner-during-upload-w.patch @@ -0,0 +1,42 @@ +From 1ebe877b8d89c74e76efd47f2a4dba6cfccf86af Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:07 -0500 +Subject: [PATCH 22/26] alsa-info.sh: Remove progress spinner during upload + without dialog + +The spinner did not actually provide information about the status +of the file upload, and caused other problems: it would repeatedly +spawn new pgrep processes (without a delay between them), and it +blocked the script if any wget process was running on the system. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index a02864d0a69d..9bc8c38a7ac6 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -857,16 +857,7 @@ else + wget -O - --tries=5 --timeout=60 --post-file=$FILE http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY &>$TEMPDIR/wget.tmp & + fi + +-#Progess spinner for wget transfer. +-i=1 +-sp="/-\|" +-echo -n ' ' +-while pgrep wget &>/dev/null +-do +- echo -en "\b${sp:i++%${#sp}:1}" +-done +- +-echo -e "\b Done!" ++echo -e " Done!" + echo "" + + fi # dialog +-- +2.16.4 + diff --git a/0023-alsa-info.sh-Condense-nested-commands-for-file-uploa.patch b/0023-alsa-info.sh-Condense-nested-commands-for-file-uploa.patch new file mode 100644 index 0000000..47527dd --- /dev/null +++ b/0023-alsa-info.sh-Condense-nested-commands-for-file-uploa.patch @@ -0,0 +1,55 @@ +From ad49ee756bbc355aa2cf7e9931c81fde17a50913 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:08 -0500 +Subject: [PATCH 23/26] alsa-info.sh: Condense nested commands for file upload + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 9bc8c38a7ac6..7560b0d5338e 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -828,15 +828,19 @@ then + + if [[ -n $DIALOG ]] + then ++ dialog --backtitle "$BGTITLE" --infobox "Uploading information to $WWWSERVICE ..." 6 70 ++else ++ echo -n "Uploading information to $WWWSERVICE ..." ++fi + + if [[ -z $PASTEBIN ]]; then +- dialog --backtitle "$BGTITLE" --infobox "Uploading information to www.alsa-project.org ..." 6 70 + wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://www.alsa-project.org/cardinfo-db/" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" + else +- dialog --backtitle "$BGTITLE" --infobox "Uploading information to www.pastebin.ca ..." 6 70 + wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY&encrypt=t&encryptpw=blahblah" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" + fi + ++if [ -n "$DIALOG" ]; then ++ + dialog --backtitle "$BGTITLE" --title "Information uploaded" --yesno "Would you like to see the uploaded information?" 5 100 + DIALOG_EXIT_CODE=$? + if [ $DIALOG_EXIT_CODE = 0 ]; then +@@ -849,14 +853,6 @@ clear + # no dialog + else + +-if [[ -z $PASTEBIN ]]; then +- echo -n "Uploading information to www.alsa-project.org ... " +- wget -O - --tries=5 --timeout=60 --post-file=$FILE http://www.alsa-project.org/cardinfo-db/ &>$TEMPDIR/wget.tmp & +-else +- echo -n "Uploading information to www.pastebin.ca ... " +- wget -O - --tries=5 --timeout=60 --post-file=$FILE http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY &>$TEMPDIR/wget.tmp & +-fi +- + echo -e " Done!" + echo "" + +-- +2.16.4 + diff --git a/0024-alsa-info.sh-Condense-nested-commands-for-formatting.patch b/0024-alsa-info.sh-Condense-nested-commands-for-formatting.patch new file mode 100644 index 0000000..9e7dbee --- /dev/null +++ b/0024-alsa-info.sh-Condense-nested-commands-for-formatting.patch @@ -0,0 +1,47 @@ +From f93d491a08c7a5c34642aac166d0329c27eaa502 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:09 -0500 +Subject: [PATCH 24/26] alsa-info.sh: Condense nested commands for formatting + upload result + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 7560b0d5338e..8b4745b68958 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -858,19 +858,15 @@ echo "" + + fi # dialog + +-# See if tput is available, and use it if it is. +-if [ -n "$TPUT" ]; then +- if [[ -z $PASTEBIN ]]; then +- FINAL_URL=$(tput setaf 1; grep "SUCCESS:" $TEMPDIR/wget.tmp | cut -d ' ' -f 2 ; tput sgr0) +- else +- FINAL_URL=$(tput setaf 1; grep "SUCCESS:" $TEMPDIR/wget.tmp | sed -n 's/.*\:\([0-9]\+\).*/http:\/\/pastebin.ca\/\1/p'; tput sgr0) +- fi ++if [ -z "$PASTEBIN" ]; then ++ FINAL_URL=$(grep "SUCCESS:" $TEMPDIR/wget.tmp | cut -d ' ' -f 2) + else +- if [[ -z $PASTEBIN ]]; then +- FINAL_URL=$(grep "SUCCESS:" $TEMPDIR/wget.tmp | cut -d ' ' -f 2) +- else +- FINAL_URL=$(grep "SUCCESS:" $TEMPDIR/wget.tmp | sed -n 's/.*\:\([0-9]\+\).*/http:\/\/pastebin.ca\/\1/p') +- fi ++ FINAL_URL=$(grep "SUCCESS:" $TEMPDIR/wget.tmp | sed -n 's/.*\:\([0-9]\+\).*/http:\/\/pastebin.ca\/\1/p') ++fi ++ ++# See if tput is available, and use it if it is. ++if [ -x "$TPUT" ]; then ++ FINAL_URL=$(tput setaf 1; printf '%s' "$FINAL_URL"; tput sgr0) + fi + + # Output the URL of the uploaded file. +-- +2.16.4 + diff --git a/0025-alsa-info.sh-Perform-test-for-wget-earlier.patch b/0025-alsa-info.sh-Perform-test-for-wget-earlier.patch new file mode 100644 index 0000000..fe08b06 --- /dev/null +++ b/0025-alsa-info.sh-Perform-test-for-wget-earlier.patch @@ -0,0 +1,111 @@ +From fe322c46e6c2ae6ce130eed70f33a42fc4f6295a Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:10 -0500 +Subject: [PATCH 25/26] alsa-info.sh: Perform test for wget earlier + +If wget is not present, do not ask about uploading the information. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 73 ++++++++++++++++++++++++-------------------------- + 1 file changed, 35 insertions(+), 38 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 8b4745b68958..399d662b0228 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -769,6 +769,41 @@ if [ -z "$WITHALL" ]; then + withall + fi + ++# Check if wget is installed, and supports --post-file. ++if ! wget --help 2>/dev/null | grep -q post-file; then ++ # We couldn't find a suitable wget. If --upload was passed, tell the user to upload manually. ++ if [ "$UPLOAD" != "yes" ]; then ++ : ++ elif [ -n "$DIALOG" ]; then ++ if [ -z "$PASTEBIN" ]; then ++ dialog --backtitle "$BGTITLE" --msgbox "Could not automatically upload output to http://www.alsa-project.org.\nPossible reasons are:\n\n 1. Couldn't find 'wget' in your PATH\n 2. Your version of wget is less than 1.8.2\n\nPlease manually upload $NFILE to http://www.alsa-project.org/cardinfo-db/ and submit your post." 25 100 ++ else ++ dialog --backtitle "$BGTITLE" --msgbox "Could not automatically upload output to http://www.pastebin.ca.\nPossible reasons are:\n\n 1. Couldn't find 'wget' in your PATH\n 2. Your version of wget is less than 1.8.2\n\nPlease manually upload $NFILE to http://www.pastebin.ca/upload.php and submit your post." 25 100 ++ fi ++ else ++ if [ -z "$PASTEBIN" ]; then ++ echo "" ++ echo "Could not automatically upload output to http://www.alsa-project.org" ++ echo "Possible reasons are:" ++ echo " 1. Couldn't find 'wget' in your PATH" ++ echo " 2. Your version of wget is less than 1.8.2" ++ echo "" ++ echo "Please manually upload $NFILE to http://www.alsa-project.org/cardinfo-db/ and submit your post." ++ echo "" ++ else ++ echo "" ++ echo "Could not automatically upload output to http://www.pastebin.ca" ++ echo "Possible reasons are:" ++ echo " 1. Couldn't find 'wget' in your PATH" ++ echo " 2. Your version of wget is less than 1.8.2" ++ echo "" ++ echo "Please manually upload $NFILE to http://www.pastebin.ca/upload.php and submit your post." ++ echo "" ++ fi ++ fi ++ UPLOAD="no" ++fi ++ + if [ "$UPLOAD" = "ask" ]; then + if [ -n "$DIALOG" ]; then + dialog --backtitle "$BGTITLE" --title "Information collected" --yes-label " UPLOAD / SHARE " --no-label " SAVE LOCALLY " --defaultno --yesno "\n\nAutomatically upload ALSA information to $WWWSERVICE?" 10 80 +@@ -822,10 +857,6 @@ if [ "$UPLOAD" = "no" ]; then + + fi # UPLOAD + +-# Test that wget is installed, and supports --post-file. Upload $FILE if it does, and prompt user to upload file if it does not. +-if [[ -n "${WGET}" ]] && [[ -x "${WGET}" ]] && [[ $(wget --help | grep post-file) ]] +-then +- + if [[ -n $DIALOG ]] + then + dialog --backtitle "$BGTITLE" --infobox "Uploading information to $WWWSERVICE ..." 6 70 +@@ -873,37 +904,3 @@ fi + echo "Your ALSA information is located at $FINAL_URL" + echo "Please inform the person helping you." + echo "" +- +-# We couldnt find a suitable wget, so tell the user to upload manually. +-else +- mv -f $FILE $NFILE || exit 1 +- KEEP_OUTPUT="yes" +- if [[ -z $DIALOG ]] +- then +- if [[ -z $PASTEBIN ]]; then +- echo "" +- echo "Could not automatically upload output to http://www.alsa-project.org" +- echo "Possible reasons are:" +- echo " 1. Couldnt find 'wget' in your PATH" +- echo " 2. Your version of wget is less than 1.8.2" +- echo "" +- echo "Please manually upload $NFILE to http://www.alsa-project.org/cardinfo-db/ and submit your post." +- echo "" +- else +- echo "" +- echo "Could not automatically upload output to http://www.pastebin.ca" +- echo "Possible reasons are:" +- echo " 1. Couldnt find 'wget' in your PATH" +- echo " 2. Your version of wget is less than 1.8.2" +- echo "" +- echo "Please manually upload $NFILE to http://www.pastebin.ca/upload.php and submit your post." +- echo "" +- fi +- else +- if [[ -z $PASTEBIN ]]; then +- dialog --backtitle "$BGTITLE" --msgbox "Could not automatically upload output to http://www.alsa-project.org.\nPossible reasons are:\n\n 1. Couldn't find 'wget' in your PATH\n 2. Your version of wget is less than 1.8.2\n\nPlease manually upload $NFILE to http://www.alsa-project,org/cardinfo-db/ and submit your post." 25 100 +- else +- dialog --backtitle "$BGTITLE" --msgbox "Could not automatically upload output to http://www.pastebin.ca.\nPossible reasons are:\n\n 1. Couldn't find 'wget' in your PATH\n 2. Your version of wget is less than 1.8.2\n\nPlease manually upload $NFILE to http://www.pastebin.ca/upload.php and submit your post." 25 100 +- fi +- fi +-fi +-- +2.16.4 + diff --git a/0026-alsa-info.sh-Warn-after-actual-upload-failure-do-not.patch b/0026-alsa-info.sh-Warn-after-actual-upload-failure-do-not.patch new file mode 100644 index 0000000..b774b9f --- /dev/null +++ b/0026-alsa-info.sh-Warn-after-actual-upload-failure-do-not.patch @@ -0,0 +1,125 @@ +From 27b5c6c19c8d3b4e994f258dc5e51571726ff924 Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Sat, 21 Dec 2019 00:32:11 -0500 +Subject: [PATCH 26/26] alsa-info.sh: Warn after actual upload failure; do not + ping server + +Check the return value of wget to determine if the upload actually +failed. If so, display the message about upload failure, then exit. + +Do not ping the web server; the result does not indicate whether a +file upload will succeed or not. + +Signed-off-by: David Ward +Signed-off-by: Takashi Iwai +--- + alsa-info/alsa-info.sh | 58 ++++++++++++++++++++++---------------------------- + 1 file changed, 25 insertions(+), 33 deletions(-) + +diff --git a/alsa-info/alsa-info.sh b/alsa-info/alsa-info.sh +index 399d662b0228..7bae30a614b0 100755 +--- a/alsa-info/alsa-info.sh ++++ b/alsa-info/alsa-info.sh +@@ -35,22 +35,12 @@ BGTITLE="ALSA-Info v $SCRIPT_VERSION" + PASTEBINKEY="C9cRIO8m/9y8Cs0nVs0FraRx7U0pHsuc" + + WGET=$(which wget 2>/dev/null | sed 's|^[^/]*||' 2>/dev/null) +-REQUIRES="mktemp grep pgrep whereis ping awk date uname cat sort dmesg amixer alsactl" ++REQUIRES="mktemp grep pgrep whereis awk date uname cat sort dmesg amixer alsactl" + + # + # Define some simple functions + # + +-pbcheck() { +- [[ $UPLOAD = "no" ]] && return +- +- if [[ -z $PASTEBIN ]]; then +- [[ $(ping -c1 www.alsa-project.org) ]] || KEEP_FILES="yes" UPLOAD="no" PBERROR="yes" +- else +- [[ $(ping -c1 www.pastebin.ca) ]] || KEEP_FILES="yes" UPLOAD="no" PBERROR="yes" +- fi +-} +- + update() { + test -z "$WGET" -o ! -x "$WGET" && return + +@@ -650,7 +640,6 @@ fi + #If no command line options are specified, then run as though --with-all was specified + if [ -z "$1" ]; then + update +- pbcheck + fi + + fi # proceed +@@ -662,7 +651,6 @@ if [ -n "$1" ]; then + case "$1" in + --pastebin) + update +- pbcheck + ;; + --update) + update +@@ -832,25 +820,11 @@ if [ "$UPLOAD" = "no" ]; then + + if [[ -n $DIALOG ]] + then +- if [[ -n $PBERROR ]]; then +- dialog --backtitle "$BGTITLE" --title "Information collected" --msgbox "An error occurred while contacting the $WWWSERVICE.\n Your information was NOT automatically uploaded.\n\nYour ALSA information is in $NFILE" 10 100 +- else +- dialog --backtitle "$BGTITLE" --title "Information collected" --msgbox "\n\nYour ALSA information is in $NFILE" 10 60 +- fi ++ dialog --backtitle "$BGTITLE" --title "Information collected" --msgbox "\n\nYour ALSA information is in $NFILE" 10 60 + else +- echo +- +- if [[ -n $PBERROR ]]; then +- echo "An error occurred while contacting the $WWWSERVICE." +- echo "Your information was NOT automatically uploaded." +- echo "" +- echo "Your ALSA information is in $NFILE" +- echo "" +- else +- echo "" +- echo "Your ALSA information is in $NFILE" +- echo "" +- fi ++ echo "" ++ echo "Your ALSA information is in $NFILE" ++ echo "" + fi + + exit +@@ -865,9 +839,27 @@ else + fi + + if [[ -z $PASTEBIN ]]; then +- wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://www.alsa-project.org/cardinfo-db/" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" ++ wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://www.alsa-project.org/cardinfo-db/" &>$TEMPDIR/wget.tmp + else +- wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY&encrypt=t&encryptpw=blahblah" &>$TEMPDIR/wget.tmp || echo "Upload failed; exit" ++ wget -O - --tries=5 --timeout=60 --post-file=$FILE "http://pastebin.ca/quiet-paste.php?api=$PASTEBINKEY&encrypt=t&encryptpw=blahblah" &>$TEMPDIR/wget.tmp ++fi ++ ++if [ $? -ne 0 ]; then ++ mv -f $FILE $NFILE || exit 1 ++ KEEP_OUTPUT="yes" ++ ++ if [ -n "$DIALOG" ]; then ++ dialog --backtitle "$BGTITLE" --title "Information not uploaded" --msgbox "An error occurred while contacting $WWWSERVICE.\n Your information was NOT automatically uploaded.\n\nYour ALSA information is in $NFILE" 10 100 ++ else ++ echo "" ++ echo "An error occurred while contacting $WWWSERVICE." ++ echo "Your information was NOT automatically uploaded." ++ echo "" ++ echo "Your ALSA information is in $NFILE" ++ echo "" ++ fi ++ ++ exit + fi + + if [ -n "$DIALOG" ]; then +-- +2.16.4 + diff --git a/alsa-utils.changes b/alsa-utils.changes index 87ff1a2..232ec51 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,3 +1,36 @@ +------------------------------------------------------------------- +Tue Jan 21 15:57:03 CET 2020 - tiwai@suse.de + +- Backport upstream patches: + A few portability fixes, alsaucm fixes and extensions, alsatplg + minor fixes, alsa-info.sh extensions: + 0001-treewide-sys-poll-to-poll.patch + 0002-treewide-Fix-wrong-formats-on-32-bit.patch + 0003-treewide-Fix-printf-formats.patch + 0004-aplay-Adjust-buffer-sizes-to-fix-snprintf-warnings.patch + 0005-aplay-Limit-VUMeter-progress-bar-to-100-for-negative.patch + 0006-alsactl-sysfs-add-sys-kernel-uevent_seqnum-check-to-.patch + 0007-alsaucm-use-the-first-sound-card-use-case-name-hw-CA.patch + 0008-alsaucm-add-text-dump-command.patch + 0009-alsaucm-add-json-dump-command.patch + 0010-alsaucm-dump-fix-the-prefixed.patch + 0011-alsactl-fix-sched-idle-set-it-really-to-SCHED_IDLE.patch + 0012-configure-Fix-linking-of-alsatplg-with-the-older-lib.patch + 0013-alsatplg-add-n-normalize-option.patch + 0014-alsatplg-add-s-sort-and-fix-memory-leaks.patch + 0015-alsatplg-fix-another-small-leak-in-normalize_config.patch + 0016-alsa-info.sh-Consolidate-PCI-device-output.patch + 0017-alsa-info.sh-Read-from-proc-modules-and-sort-the-res.patch + 0018-alsa-info.sh-Simplify-iteration-over-cards-when-call.patch + 0019-alsa-info.sh-Use-existing-function-to-print-ALSA-con.patch + 0020-alsa-info.sh-Exit-script-after-writing-information-t.patch + 0021-alsa-info.sh-Replace-gauge-with-infobox-for-upload-d.patch + 0022-alsa-info.sh-Remove-progress-spinner-during-upload-w.patch + 0023-alsa-info.sh-Condense-nested-commands-for-file-uploa.patch + 0024-alsa-info.sh-Condense-nested-commands-for-formatting.patch + 0025-alsa-info.sh-Perform-test-for-wget-earlier.patch + 0026-alsa-info.sh-Warn-after-actual-upload-failure-do-not.patch + ------------------------------------------------------------------- Fri Dec 20 16:51:55 CET 2019 - tiwai@suse.de diff --git a/alsa-utils.spec b/alsa-utils.spec index c2257c3..b94aed5 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -1,7 +1,7 @@ # # spec file for package alsa-utils # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,6 +16,7 @@ # +%define do_autoreconf 1 %define _udevdir %(pkg-config --variable=udevdir udev) Name: alsa-utils Version: 1.2.1 @@ -28,10 +29,35 @@ Source: ftp://ftp.alsa-project.org/pub/utils/alsa-utils-%{version}.tar.b Source1: 01beep.conf Source2: sound-extra.service Source5: load-sound-modules.sh +Patch1: 0001-treewide-sys-poll-to-poll.patch +Patch2: 0002-treewide-Fix-wrong-formats-on-32-bit.patch +Patch3: 0003-treewide-Fix-printf-formats.patch +Patch4: 0004-aplay-Adjust-buffer-sizes-to-fix-snprintf-warnings.patch +Patch5: 0005-aplay-Limit-VUMeter-progress-bar-to-100-for-negative.patch +Patch6: 0006-alsactl-sysfs-add-sys-kernel-uevent_seqnum-check-to-.patch +Patch7: 0007-alsaucm-use-the-first-sound-card-use-case-name-hw-CA.patch +Patch8: 0008-alsaucm-add-text-dump-command.patch +Patch9: 0009-alsaucm-add-json-dump-command.patch +Patch10: 0010-alsaucm-dump-fix-the-prefixed.patch +Patch11: 0011-alsactl-fix-sched-idle-set-it-really-to-SCHED_IDLE.patch +Patch12: 0012-configure-Fix-linking-of-alsatplg-with-the-older-lib.patch +Patch13: 0013-alsatplg-add-n-normalize-option.patch +Patch14: 0014-alsatplg-add-s-sort-and-fix-memory-leaks.patch +Patch15: 0015-alsatplg-fix-another-small-leak-in-normalize_config.patch +Patch16: 0016-alsa-info.sh-Consolidate-PCI-device-output.patch +Patch17: 0017-alsa-info.sh-Read-from-proc-modules-and-sort-the-res.patch +Patch18: 0018-alsa-info.sh-Simplify-iteration-over-cards-when-call.patch +Patch19: 0019-alsa-info.sh-Use-existing-function-to-print-ALSA-con.patch +Patch20: 0020-alsa-info.sh-Exit-script-after-writing-information-t.patch +Patch21: 0021-alsa-info.sh-Replace-gauge-with-infobox-for-upload-d.patch +Patch22: 0022-alsa-info.sh-Remove-progress-spinner-during-upload-w.patch +Patch23: 0023-alsa-info.sh-Condense-nested-commands-for-file-uploa.patch +Patch24: 0024-alsa-info.sh-Condense-nested-commands-for-formatting.patch +Patch25: 0025-alsa-info.sh-Perform-test-for-wget-earlier.patch +Patch26: 0026-alsa-info.sh-Warn-after-actual-upload-failure-do-not.patch Patch101: alsa-utils-configure-version-revert.patch BuildRequires: alsa-devel BuildRequires: alsa-topology-devel -BuildRequires: automake BuildRequires: fftw3-devel BuildRequires: libsamplerate-devel BuildRequires: ncurses-devel @@ -40,6 +66,9 @@ BuildRequires: python3-docutils BuildRequires: xmlto BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(udev) +%if 0%{?do_autoreconf} +BuildRequires: automake +%endif Requires: alsa # for alsa-info.sh Requires: dialog @@ -62,6 +91,32 @@ and test audio before and after PM state changes. %prep %setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 %if 0%{?do_autoreconf} %patch101 -p1 # fix stupid automake's automatic action @@ -71,6 +126,7 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am %build export AUTOMAKE_JOBS="%{?_smp_mflags}" %if 0%{?do_autoreconf} +gettextize -c -f --no-changelog autoreconf -fi %endif %configure --with-curses=ncursesw \