Compare commits
10 Commits
86849d295b
...
fff1fc9f6d
Author | SHA1 | Date |
---|---|---|
Sanchayan Maity | fff1fc9f6d | |
Sanchayan Maity | 92f1a56c46 | |
Ingo Feinerer | b14e039639 | |
Aaron Marcher | 93daf4f35e | |
Michael Buch | a1ac203d16 | |
Ingo Feinerer | 10bdf01b71 | |
Ingo Feinerer | d518472e62 | |
Michael Buch | a9193a757a | |
Ingo Feinerer | c1dc896c80 | |
Michael Buch | e724907cc3 |
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
slstatus
|
||||
config.h
|
2
LICENSE
2
LICENSE
|
@ -18,6 +18,8 @@ Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net>
|
|||
Copyright 2018 David Demelier <markand@malikania.fr>
|
||||
Copyright 2018-2019 Michael Buch <michaelbuch12@gmail.com>
|
||||
Copyright 2018 Ian Remmler <ian@remmler.org>
|
||||
Copyright 2016-2019 Joerg Jung <jung@openbsd.org>
|
||||
Copyright 2019 Ingo Feinerer <feinerer@logic.at>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
3
README
3
README
|
@ -32,13 +32,14 @@ Features
|
|||
|
||||
Requirements
|
||||
------------
|
||||
Currently slstatus works on FreeBSD, Linux and OpenBSD.
|
||||
In order to build slstatus you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (slstatus is installed into the
|
||||
/usr/local namespace by default). Uncomment OSSLIBS on OpenBSD.
|
||||
/usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install slstatus (if
|
||||
necessary as root):
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
cpu_perc(void)
|
||||
{
|
||||
static long double a[7];
|
||||
long double b[7];
|
||||
long double b[7], sum;
|
||||
|
||||
memcpy(b, a, sizeof(b));
|
||||
/* cpu user nice system idle iowait irq softirq */
|
||||
|
@ -37,13 +37,16 @@
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) -
|
||||
(a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]);
|
||||
|
||||
if (sum == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bprintf("%d", (int)(100 *
|
||||
((b[0] + b[1] + b[2] + b[5] + b[6]) -
|
||||
(a[0] + a[1] + a[2] + a[5] + a[6])) /
|
||||
((b[0] + b[1] + b[2] + b[3] + b[4] + b[5] +
|
||||
b[6]) -
|
||||
(a[0] + a[1] + a[2] + a[3] + a[4] + a[5] +
|
||||
a[6]))));
|
||||
(a[0] + a[1] + a[2] + a[5] + a[6])) / sum));
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
|
@ -53,8 +56,7 @@
|
|||
const char *
|
||||
cpu_freq(void)
|
||||
{
|
||||
int mib[2];
|
||||
uintmax_t freq;
|
||||
int freq, mib[2];
|
||||
size_t size;
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
|
@ -76,7 +78,7 @@
|
|||
{
|
||||
int mib[2];
|
||||
static uintmax_t a[CPUSTATES];
|
||||
uintmax_t b[CPUSTATES];
|
||||
uintmax_t b[CPUSTATES], sum;
|
||||
size_t size;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
|
@ -93,15 +95,18 @@
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
|
||||
|
||||
if (sum == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bprintf("%d", 100 *
|
||||
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
|
||||
a[CP_INTR]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
|
||||
b[CP_INTR])) /
|
||||
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
|
||||
a[CP_INTR] + a[CP_IDLE]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
|
||||
b[CP_INTR] + b[CP_IDLE])));
|
||||
b[CP_INTR])) / sum);
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/param.h>
|
||||
|
@ -130,7 +135,7 @@
|
|||
{
|
||||
size_t size;
|
||||
static long a[CPUSTATES];
|
||||
long b[CPUSTATES];
|
||||
long b[CPUSTATES], sum;
|
||||
|
||||
size = sizeof(a);
|
||||
memcpy(b, a, sizeof(b));
|
||||
|
@ -143,14 +148,17 @@
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
|
||||
|
||||
if (sum == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bprintf("%d", 100 *
|
||||
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
|
||||
a[CP_INTR]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
|
||||
b[CP_INTR])) /
|
||||
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
|
||||
a[CP_INTR] + a[CP_IDLE]) -
|
||||
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
|
||||
b[CP_INTR] + b[CP_IDLE])));
|
||||
b[CP_INTR])) / sum);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -156,4 +156,67 @@
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <unistd.h>
|
||||
#include <vm/vm_param.h>
|
||||
|
||||
const char *
|
||||
ram_free(void) {
|
||||
struct vmtotal vm_stats;
|
||||
int mib[] = {CTL_VM, VM_TOTAL};
|
||||
size_t len;
|
||||
|
||||
len = sizeof(struct vmtotal);
|
||||
if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) == -1
|
||||
|| !len)
|
||||
return NULL;
|
||||
|
||||
return fmt_human(vm_stats.t_free * getpagesize(), 1024);
|
||||
}
|
||||
|
||||
const char *
|
||||
ram_total(void) {
|
||||
long npages;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(npages);
|
||||
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1
|
||||
|| !len)
|
||||
return NULL;
|
||||
|
||||
return fmt_human(npages * getpagesize(), 1024);
|
||||
}
|
||||
|
||||
const char *
|
||||
ram_perc(void) {
|
||||
long npages;
|
||||
long active;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(npages);
|
||||
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1
|
||||
|| !len)
|
||||
return NULL;
|
||||
|
||||
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1
|
||||
|| !len)
|
||||
return NULL;
|
||||
|
||||
return bprintf("%d", active * 100 / npages);
|
||||
}
|
||||
|
||||
const char *
|
||||
ram_used(void) {
|
||||
long active;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(active);
|
||||
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1
|
||||
|| !len)
|
||||
return NULL;
|
||||
|
||||
return fmt_human(active * getpagesize(), 1024);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -197,4 +197,88 @@
|
|||
|
||||
return fmt_human(used * 1024, 1024);
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <kvm.h>
|
||||
|
||||
static int getswapinfo(struct kvm_swap *swap_info, size_t size)
|
||||
{
|
||||
kvm_t *kd;
|
||||
|
||||
kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL);
|
||||
if(kd == NULL) {
|
||||
warn("kvm_openfiles '/dev/null':");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) == -1) {
|
||||
warn("kvm_getswapinfo:");
|
||||
kvm_close(kd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
kvm_close(kd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *
|
||||
swap_free(void)
|
||||
{
|
||||
struct kvm_swap swap_info[1];
|
||||
long used, total;
|
||||
|
||||
if(!getswapinfo(swap_info, 1))
|
||||
return NULL;
|
||||
|
||||
total = swap_info[0].ksw_total;
|
||||
used = swap_info[0].ksw_used;
|
||||
|
||||
return fmt_human((total - used) * getpagesize(), 1024);
|
||||
}
|
||||
|
||||
const char *
|
||||
swap_perc(void)
|
||||
{
|
||||
struct kvm_swap swap_info[1];
|
||||
long used, total;
|
||||
|
||||
if(!getswapinfo(swap_info, 1))
|
||||
return NULL;
|
||||
|
||||
total = swap_info[0].ksw_total;
|
||||
used = swap_info[0].ksw_used;
|
||||
|
||||
return bprintf("%d", used * 100 / total);
|
||||
}
|
||||
|
||||
const char *
|
||||
swap_total(void)
|
||||
{
|
||||
struct kvm_swap swap_info[1];
|
||||
long total;
|
||||
|
||||
if(!getswapinfo(swap_info, 1))
|
||||
return NULL;
|
||||
|
||||
total = swap_info[0].ksw_total;
|
||||
|
||||
return fmt_human(total * getpagesize(), 1024);
|
||||
}
|
||||
|
||||
const char *
|
||||
swap_used(void)
|
||||
{
|
||||
struct kvm_swap swap_info[1];
|
||||
long used;
|
||||
|
||||
if(!getswapinfo(swap_info, 1))
|
||||
return NULL;
|
||||
|
||||
used = swap_info[0].ksw_used;
|
||||
|
||||
return fmt_human(used * getpagesize(), 1024);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,44 +2,108 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#if defined(__OpenBSD__)
|
||||
#include <soundcard.h>
|
||||
#else
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../util.h"
|
||||
|
||||
const char *
|
||||
vol_perc(const char *card)
|
||||
{
|
||||
size_t i;
|
||||
int v, afd, devmask;
|
||||
char *vnames[] = SOUND_DEVICE_NAMES;
|
||||
#if defined(__OpenBSD__)
|
||||
#include <sys/audioio.h>
|
||||
|
||||
if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) {
|
||||
warn("open '%s':", card);
|
||||
return NULL;
|
||||
}
|
||||
const char *
|
||||
vol_perc(const char *card)
|
||||
{
|
||||
static int cls = -1;
|
||||
mixer_devinfo_t mdi;
|
||||
mixer_ctrl_t mc;
|
||||
int afd = -1, m = -1, v = -1;
|
||||
|
||||
if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
|
||||
warn("ioctl 'SOUND_MIXER_READ_DEVMASK':");
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < LEN(vnames); i++) {
|
||||
if (devmask & (1 << i) && !strcmp("vol", vnames[i])) {
|
||||
if (ioctl(afd, MIXER_READ(i), &v) < 0) {
|
||||
warn("ioctl 'MIXER_READ(%ld)':", i);
|
||||
if ((afd = open(card, O_RDONLY)) < 0) {
|
||||
warn("open '%s':", card);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (mdi.index = 0; cls == -1; mdi.index++) {
|
||||
if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) {
|
||||
warn("ioctl 'AUDIO_MIXER_DEVINFO':");
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
if (mdi.type == AUDIO_MIXER_CLASS &&
|
||||
!strncmp(mdi.label.name,
|
||||
AudioCoutputs,
|
||||
MAX_AUDIO_DEV_LEN))
|
||||
cls = mdi.index;
|
||||
}
|
||||
for (mdi.index = 0; v == -1 || m == -1; mdi.index++) {
|
||||
if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) {
|
||||
warn("ioctl 'AUDIO_MIXER_DEVINFO':");
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
if (mdi.mixer_class == cls &&
|
||||
((mdi.type == AUDIO_MIXER_VALUE &&
|
||||
!strncmp(mdi.label.name,
|
||||
AudioNmaster,
|
||||
MAX_AUDIO_DEV_LEN)) ||
|
||||
(mdi.type == AUDIO_MIXER_ENUM &&
|
||||
!strncmp(mdi.label.name,
|
||||
AudioNmute,
|
||||
MAX_AUDIO_DEV_LEN)))) {
|
||||
mc.dev = mdi.index, mc.type = mdi.type;
|
||||
if (ioctl(afd, AUDIO_MIXER_READ, &mc) < 0) {
|
||||
warn("ioctl 'AUDIO_MIXER_READ':");
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
if (mc.type == AUDIO_MIXER_VALUE)
|
||||
v = mc.un.value.num_channels == 1 ?
|
||||
mc.un.value.level[AUDIO_MIXER_LEVEL_MONO] :
|
||||
(mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] >
|
||||
mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] ?
|
||||
mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] :
|
||||
mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
|
||||
else if (mc.type == AUDIO_MIXER_ENUM)
|
||||
m = mc.un.ord;
|
||||
}
|
||||
}
|
||||
|
||||
close(afd);
|
||||
|
||||
return bprintf("%d", m ? 0 : v * 100 / 255);
|
||||
}
|
||||
#else
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
close(afd);
|
||||
const char *
|
||||
vol_perc(const char *card)
|
||||
{
|
||||
size_t i;
|
||||
int v, afd, devmask;
|
||||
char *vnames[] = SOUND_DEVICE_NAMES;
|
||||
|
||||
return bprintf("%d", v & 0xff);
|
||||
}
|
||||
if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) {
|
||||
warn("open '%s':", card);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
|
||||
warn("ioctl 'SOUND_MIXER_READ_DEVMASK':");
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < LEN(vnames); i++) {
|
||||
if (devmask & (1 << i) && !strcmp("vol", vnames[i])) {
|
||||
if (ioctl(afd, MIXER_READ(i), &v) < 0) {
|
||||
warn("ioctl 'MIXER_READ(%ld)':", i);
|
||||
close(afd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(afd);
|
||||
|
||||
return bprintf("%d", v & 0xff);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
|
||||
#include "../util.h"
|
||||
|
||||
#define RSSI_TO_PERC(rssi) \
|
||||
rssi >= -50 ? 100 : \
|
||||
(rssi <= -100 ? 0 : \
|
||||
(2 * (rssi + 100)))
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <limits.h>
|
||||
#include <linux/wireless.h>
|
||||
|
@ -150,9 +155,7 @@
|
|||
if (nr.nr_max_rssi) {
|
||||
q = IEEE80211_NODEREQ_RSSI(&nr);
|
||||
} else {
|
||||
q = nr.nr_rssi >= -50 ? 100 :
|
||||
(nr.nr_rssi <= -100 ? 0 :
|
||||
(2 * (nr.nr_rssi + 100)));
|
||||
q = RSSI_TO_PERC(nr.nr_rssi);
|
||||
}
|
||||
return bprintf("%d", q);
|
||||
}
|
||||
|
@ -171,4 +174,99 @@
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <net/if.h>
|
||||
#include <net80211/ieee80211_ioctl.h>
|
||||
|
||||
int
|
||||
load_ieee80211req(int sock, const char *interface, void *data, int type, size_t *len)
|
||||
{
|
||||
char warn_buf[256];
|
||||
struct ieee80211req ireq;
|
||||
memset(&ireq, 0, sizeof(ireq));
|
||||
ireq.i_type = type;
|
||||
ireq.i_data = (caddr_t) data;
|
||||
ireq.i_len = *len;
|
||||
|
||||
strlcpy(ireq.i_name, interface, sizeof(ireq.i_name));
|
||||
if (ioctl(sock, SIOCG80211, &ireq) < 0) {
|
||||
snprintf(warn_buf, sizeof(warn_buf),
|
||||
"ioctl: 'SIOCG80211': %d", type);
|
||||
warn(warn_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*len = ireq.i_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *
|
||||
wifi_perc(const char *interface)
|
||||
{
|
||||
union {
|
||||
struct ieee80211req_sta_req sta;
|
||||
uint8_t buf[24 * 1024];
|
||||
} info;
|
||||
uint8_t bssid[IEEE80211_ADDR_LEN];
|
||||
int rssi_dbm;
|
||||
int sockfd;
|
||||
size_t len;
|
||||
const char *fmt;
|
||||
|
||||
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
warn("socket 'AF_INET':");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Retreive MAC address of interface */
|
||||
len = IEEE80211_ADDR_LEN;
|
||||
fmt = NULL;
|
||||
if (load_ieee80211req(sockfd, interface, &bssid, IEEE80211_IOC_BSSID, &len))
|
||||
{
|
||||
/* Retrieve info on station with above BSSID */
|
||||
memset(&info, 0, sizeof(info));
|
||||
memcpy(info.sta.is_u.macaddr, bssid, sizeof(bssid));
|
||||
|
||||
len = sizeof(info);
|
||||
if (load_ieee80211req(sockfd, interface, &info, IEEE80211_IOC_STA_INFO, &len)) {
|
||||
rssi_dbm = info.sta.info[0].isi_noise +
|
||||
info.sta.info[0].isi_rssi / 2;
|
||||
|
||||
fmt = bprintf("%d", RSSI_TO_PERC(rssi_dbm));
|
||||
}
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return fmt;
|
||||
}
|
||||
|
||||
const char *
|
||||
wifi_essid(const char *interface)
|
||||
{
|
||||
char ssid[IEEE80211_NWID_LEN + 1];
|
||||
size_t len;
|
||||
int sockfd;
|
||||
const char *fmt;
|
||||
|
||||
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
warn("socket 'AF_INET':");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fmt = NULL;
|
||||
len = sizeof(ssid);
|
||||
memset(&ssid, 0, len);
|
||||
if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len )) {
|
||||
if (len < sizeof(ssid))
|
||||
len += 1;
|
||||
else
|
||||
len = sizeof(ssid);
|
||||
|
||||
ssid[len - 1] = '\0';
|
||||
fmt = bprintf("%s", ssid);
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return fmt;
|
||||
}
|
||||
#endif
|
||||
|
|
11
config.def.h
11
config.def.h
|
@ -63,5 +63,14 @@ static const char unknown_str[] = "n/a";
|
|||
*/
|
||||
static const struct arg args[] = {
|
||||
/* function format argument */
|
||||
{ datetime, "%s", "%F %T" },
|
||||
{ wifi_essid, " [WIFI: %s" , "wlp58s0" },
|
||||
{ wifi_perc, " SS: %s" , "wlp58s0" },
|
||||
{ netspeed_tx, " TX: %s" , "wlp58s0" },
|
||||
{ netspeed_rx, " RX: %s]" , "wlp58s0" },
|
||||
{ battery_perc, " [ %s]" , "BAT0" },
|
||||
{ load_avg, " [LOAD: %s]" , NULL },
|
||||
{ cpu_perc, " [ %s%%]" , NULL },
|
||||
{ ram_perc, " [ %s%%]" , NULL },
|
||||
{ datetime, " | %s |" , "%a, %b %d"},
|
||||
{ datetime, " %s " , "%I:%M %p" },
|
||||
};
|
||||
|
|
|
@ -14,7 +14,6 @@ X11LIB = /usr/X11R6/lib
|
|||
CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os
|
||||
LDFLAGS = -L$(X11LIB) -s
|
||||
# OpenBSD: add -lossaudio
|
||||
LDLIBS = -lX11
|
||||
|
||||
# compiler and linker
|
||||
|
|
Loading…
Reference in New Issue