scripts: sync with upstream

This commit is contained in:
coolsnowwolf 2022-10-19 20:39:19 +08:00
parent 80b72c1cc6
commit 66d86d2371
71 changed files with 4659 additions and 4696 deletions

View File

@ -5,7 +5,7 @@
mainmenu "OpenWrt Configuration"
config MODULES
option modules
modules
bool
default y
@ -13,6 +13,14 @@ config HAVE_DOT_CONFIG
bool
default y
HOST_OS := $(shell, uname)
config HOST_OS_LINUX
def_bool $(shell, ./config/check-uname.sh Linux)
config HOST_OS_MACOS
def_bool $(shell, ./config/check-uname.sh Darwin)
source "target/Config.in"
source "config/Config-images.in"

View File

@ -14,7 +14,7 @@ $(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt dir
world:
DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep '/usr' -m 1)
DISTRO_PKG_CONFIG:=$(shell $(TOPDIR)/scripts/command_all.sh pkg-config | grep '/usr' -m 1)
export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
ifneq ($(OPENWRT_BUILD),1)
@ -38,7 +38,7 @@ else
include tools/Makefile
include toolchain/Makefile
$(toolchain/stamp-compile): $(tools/stamp-compile)
$(toolchain/stamp-compile): $(tools/stamp-compile) $(if $(CONFIG_BUILDBOT),toolchain_rebuild_check)
$(target/stamp-compile): $(toolchain/stamp-compile) $(tools/stamp-compile) $(BUILD_DIR)/.prepared
$(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
$(package/stamp-install): $(package/stamp-compile)
@ -50,14 +50,23 @@ printdb:
prepare: $(target/stamp-compile)
clean: FORCE
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages
_clean: FORCE
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(TOPDIR)/staging_dir/packages
dirclean: clean
rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
clean: _clean
rm -rf $(BUILD_LOG_DIR)
targetclean: _clean
rm -rf $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
dirclean: targetclean clean
rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(BUILD_DIR_BASE)/host
rm -rf $(TMP_DIR)
$(MAKE) -C $(TOPDIR)/scripts/config clean
toolchain_rebuild_check:
$(SCRIPT_DIR)/check-toolchain-clean.sh
cacheclean:
ifneq ($(CONFIG_CCACHE),)
$(STAGING_DIR_HOST)/bin/ccache -C

1
config/check-uname.sh Executable file
View File

@ -0,0 +1 @@
[ "$(uname)" = "$1" ] && echo y || echo n

View File

@ -62,7 +62,6 @@ ARCH_PACKAGES:=$(call qstrip,$(CONFIG_TARGET_ARCH_PACKAGES))
BOARD:=$(call qstrip,$(CONFIG_TARGET_BOARD))
SUBTARGET:=$(call qstrip,$(CONFIG_TARGET_SUBTARGET))
TARGET_OPTIMIZATION:=$(call qstrip,$(CONFIG_TARGET_OPTIMIZATION))
export EXTRA_OPTIMIZATION:=$(filter-out -fno-plt,$(call qstrip,$(CONFIG_EXTRA_OPTIMIZATION)))
TARGET_SUFFIX=$(call qstrip,$(CONFIG_TARGET_SUFFIX))
BUILD_SUFFIX:=$(call qstrip,$(CONFIG_BUILD_SUFFIX))
SUBDIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR})
@ -110,7 +109,7 @@ $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1),
)
endef
DL_DIR:=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)
DL_DIR=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)$(if $(DL_SUBDIR),/$(DL_SUBDIR))
OUTPUT_DIR:=$(if $(call qstrip,$(CONFIG_BINARY_FOLDER)),$(call qstrip,$(CONFIG_BINARY_FOLDER)),$(TOPDIR)/bin)
BIN_DIR:=$(OUTPUT_DIR)/targets/$(BOARD)/$(SUBTARGET)
INCLUDE_DIR:=$(TOPDIR)/include
@ -138,11 +137,7 @@ else
endif
ifeq ($(or $(CONFIG_EXTERNAL_TOOLCHAIN),$(CONFIG_TARGET_uml)),)
ifeq ($(CONFIG_GCC_USE_IREMAP),y)
iremap = -iremap$(1):$(2)
else
iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2)
endif
iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2)
endif
PACKAGE_DIR:=$(BIN_DIR)/packages
@ -213,7 +208,6 @@ ifndef DUMP
ifneq ($(TOOLCHAIN_LIB_DIRS),)
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
endif
TARGET_PATH:=$(TOOLCHAIN_DIR)/bin:$(TARGET_PATH)
endif
endif
endif
@ -244,23 +238,17 @@ export PKG_CONFIG
HOSTCC:=gcc
HOSTCXX:=g++
HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR_HOSTPKG)/include -I$(STAGING_DIR)/host/include)
HOST_CXXFLAGS:=
HOST_CFLAGS:=-O2 $(HOST_CPPFLAGS)
HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR_HOSTPKG)/lib -L$(STAGING_DIR)/host/lib)
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
TARGET_AR:=$(TARGET_CROSS)gcc-ar
TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib
TARGET_NM:=$(TARGET_CROSS)gcc-nm
else
TARGET_AR:=$(TARGET_CROSS)ar
TARGET_RANLIB:=$(TARGET_CROSS)ranlib
TARGET_NM:=$(TARGET_CROSS)nm
endif
BUILD_KEY=$(TOPDIR)/key-build
FAKEROOT:=$(STAGING_DIR_HOST)/bin/fakeroot
TARGET_AR:=$(TARGET_CROSS)gcc-ar
TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib
TARGET_NM:=$(TARGET_CROSS)gcc-nm
TARGET_CC:=$(TARGET_CROSS)gcc
TARGET_CXX:=$(TARGET_CROSS)g++
KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh
@ -269,9 +257,6 @@ ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e
MKHASH:=$(STAGING_DIR_HOST)/bin/mkhash
# MKHASH is used in /scripts, so we export it here.
export MKHASH
# DOWNLOAD_CHECK_CERTIFICATE is used in /scripts, so we export it here.
DOWNLOAD_CHECK_CERTIFICATE:=$(CONFIG_DOWNLOAD_CHECK_CERTIFICATE)
export DOWNLOAD_CHECK_CERTIFICATE
CP:=cp -fpR
LN:=ln -sf
XARGS:=xargs -r

86
scripts/cameo-imghdr.py Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022 Luiz Angelo Daros de Luca <luizluca@gmail.com>
#
# Cameo Image header geneator, used by some D-Link DGS-1210 switches
# and APRESIA ApresiaLightGS series
#
import argparse
import pathlib
import socket
import struct
MODEL_LEN = 20
SIGNATURE_LEN = 16
LINUXLOAD_LEN = 10
BUFSIZE = 4096
parser = argparse.ArgumentParser(description='Generate Cameo firmware header.')
parser.add_argument('source_file', type=argparse.FileType('rb'))
parser.add_argument('dest_file', type=argparse.FileType('wb'))
parser.add_argument('model')
parser.add_argument('signature')
parser.add_argument('partition', type=int, choices=range(0,10),
metavar="partition=[0-9]",help="partition id")
parser.add_argument('customer_signature', type=int, choices=range(0,10),
metavar="customer_signature=[0-9]",
help="customer signature")
parser.add_argument('board_version', type=int, choices=range(0,2**32),
metavar="board_version=[0-4294967295]",
help="board version")
parser.add_argument('linux_loadaddr', nargs='?',
help="Kernel start address in 0xFFFFFFFF format")
args = parser.parse_args()
if len(args.model) > MODEL_LEN:
raise ValueError(f"Model '{args.model}' is greater than {MODEL_LEN} bytes")
if len(args.signature) > SIGNATURE_LEN:
raise ValueError(f"Signature '{args.signature}' is greater than"
f"{SIGNATURE_LEN} bytes")
if args.signature == "os":
if args.linux_loadaddr:
if len(args.linux_loadaddr) > LINUXLOAD_LEN:
raise ValueError(f"linux_loadaddr '{args.linux_loadaddr}' is greater"
f"than {LINUXLOAD_LEN} bytes")
if (args.linux_loadaddr[0:2] != "0x"):
raise ValueError(f"linux_loadaddr '{args.linux_loadaddr}' must use"
f"the 0x789ABCDE format")
int(args.linux_loadaddr[2:],16)
else:
raise ValueError(f"linux_loadaddr is required for signature 'os'")
else:
args.linux_loadaddr = ""
checksum = 0
size = 0
while True:
buf = args.source_file.read(BUFSIZE)
if not buf:
break
checksum = sum(iter(buf),checksum) % (1<<32)
size += len(buf)
args.dest_file.write(struct.pack('!I', checksum))
args.dest_file.write(struct.pack(f'{MODEL_LEN}s',
args.model.encode("ascii")))
args.dest_file.write(struct.pack(f'{SIGNATURE_LEN}s',
args.signature.encode("ascii")))
args.dest_file.write(struct.pack('!B', args.partition))
args.dest_file.write(struct.pack('!B', 0x40)) # ??? This header size?
args.dest_file.write(struct.pack('!B', 0x00)) # ??? Encrypted?
args.dest_file.write(struct.pack('!B', args.customer_signature))
args.dest_file.write(struct.pack('!I', args.board_version))
args.dest_file.write(struct.pack('!I', size))
args.dest_file.write(struct.pack(f'{LINUXLOAD_LEN}s',
args.linux_loadaddr.encode("ascii")))
args.dest_file.write(struct.pack('!2x'))
args.source_file.seek(0)
while True:
buf = args.source_file.read(BUFSIZE)
if not buf:
break
args.dest_file.write(buf)

117
scripts/cameo-tag.py Executable file
View File

@ -0,0 +1,117 @@
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022 OpenWrt.org
#
# ./cameo-tag.py <uImageFileName> <OffsetOfRootFS>
#
# CAMEO tag generator used for the D-Link DGS-1210 switches. Their U-Boot
# loader checks for the string CAMEOTAG and a checksum in the kernel and
# rootfs partitions. If not found it complains about the boot image.
# Nevertheless it will boot if the tags are available in the secondary
# boot partitions. If some day we want to overwrite the original vendor
# partition we must have the tags in place. To solve this we insert the
# tag two times into the kernel image.
#
# To understand what we do here it is helpful to explain how the original
# CAMEO tag generation/checking works. The firmware consists of two parts.
# A kernel uImage (<1.5MB) and a rootfs image (<12MB) that are written to
# their respective mtd partitions. The default generator simply checksums
# both parts and appends 16 bytes [<CAMEOTAG><0001><checksum>] to each part.
# The checksum is only an addition of all preceding bytes (b0+b1+b2+...).
# A tag does not interfere with any data in the images itself. During boot
# the loader will scan all primary/secondary partitions (2*kernel, 2*rootfs)
# until it finds the CAMEO tag. If checksums match everything is fine.
# If all 4 fail we are lost. Luckily the loader does not care about where
# the tags are located and ignores any data beyond a tag.
#
# The OpenWrt image consists of a kernel (>1.5MB) and a rootfs. There is
# no chance to add CAMEO tags at the default locations, since the kernel spans
# both the original kernel partition and the start of the rootfs partition.
# This would leave the kernel partition without a tag. So we must find suitable
# space.
#
# Location for original kernel partition is at the end of the uImage header.
# We will reuse the last bytes of the IH_NAME field. This is the tricky part
# because we have the header CRC and the CAMEO checksum that must match the
# whole header. uImage header CRC checksums all data except the CRC itself. The
# for CAMEO checksum in turn, checksums all preceding data except itself.
# Changing one of both results in a change of the other, but data trailing the
# CAMEO checksum only influences the CRC.
#
# Location for original rootfs partition is very simple. It is behind the
# OpenWrt compressed kernel image file that spans into the rootfs. So
# the tag will be written somewhere to the following rootfs partition and
# can be found by U-Boot. The CAMEO checksum calculation must start at the
# offset of the original rootfs partition and includes the "second" half of the
# "split" kernel uImage.
import argparse
import os
import zlib
READ_UNTIL_EOF = -1
UIMAGE_HEADER_SIZE = 64
UIMAGE_CRC_OFF = 4
UIMAGE_CRC_END = 8
UIMAGE_NAME_OFF = 32
UIMAGE_NAME_END = 56
UIMAGE_SUM_OFF = 56
UIMAGE_SUM_END = 60
UIMAGE_INV_OFF = 60
UIMAGE_INV_END = 64
CAMEO_TAG = bytes([0x43, 0x41, 0x4d, 0x45, 0x4f, 0x54, 0x41, 0x47, 0x00, 0x00, 0x00, 0x01])
IMAGE_NAME = bytes([0x4f, 0x70, 0x65, 0x6e, 0x57, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00])
CRC_00 = bytes([0x00] * 4)
CRC_FF = bytes([0xff] * 4)
def read_buffer(offset, count):
args.uimage_file.seek(offset)
return bytearray(args.uimage_file.read(count))
def write_buffer(whence, buf):
args.uimage_file.seek(0, whence)
args.uimage_file.write(buf)
def cameosum(buf):
return (sum(buf) & 0xffffffff).to_bytes(4, 'big')
def invertcrc(buf):
return (zlib.crc32(buf) ^ 0xffffffff).to_bytes(4, 'little')
def checksum_header(buf):
# To efficently get a combination, we will make use of the following fact:
# crc32(data + littleendian(crc32(data) ^ 0xffffffff)) = 0xffffffff
#
# After manipulation the uImage header looks like this:
# [...<ffffffff>...<OpenWrt><000000><CAMEOTAG><0001><checksum><InvCRC>]
buf[UIMAGE_NAME_OFF:UIMAGE_NAME_END] = IMAGE_NAME + CAMEO_TAG
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_FF
buf[UIMAGE_SUM_OFF:UIMAGE_SUM_END] = cameosum(buf[0:UIMAGE_NAME_END])
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_00
buf[UIMAGE_INV_OFF:UIMAGE_INV_END] = invertcrc(buf[0:UIMAGE_SUM_END])
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_FF
return buf
parser = argparse.ArgumentParser(description='Insert CAMEO firmware tags.')
parser.add_argument('uimage_file', type=argparse.FileType('r+b'))
parser.add_argument('rootfs_start', type=int)
args = parser.parse_args()
args.uimage_file.seek(0, os.SEEK_END)
if args.uimage_file.tell() <= args.rootfs_start:
raise ValueError(f"uImage must be larger than {args.rootfs_start} bytes")
# tag for the uImage Header of 64 bytes inside the kernel
# partition. Read and mangle it so it contains a valid CAMEO tag
# and checksum that matches perfectly to the uImage header CRC.
buf = checksum_header(read_buffer(0, UIMAGE_HEADER_SIZE))
write_buffer(os.SEEK_SET, buf)
# tag for the second part of the kernel that resides in the
# vendor rootfs partition. For this we will add the CAMEO tag
# and the checksum to the end of the image.
buf = read_buffer(args.rootfs_start, READ_UNTIL_EOF)
write_buffer(os.SEEK_END, CAMEO_TAG + cameosum(buf + CAMEO_TAG))

View File

@ -17,175 +17,123 @@ CFE Partition Tag
import argparse
import os
import struct
import binascii
PART_NAME_SIZE = 33
PART_VERSION_SIZE = 21
CRC32_INIT = 0xFFFFFFFF
CRC32_TABLE = [
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
]
def auto_int(x):
return int(x, 0)
return int(x, 0)
def crc32(bytes, size, crc):
i = 0
while (i < size):
crc = (crc >> 8) ^ CRC32_TABLE[(crc ^ bytes[i]) & 0xff]
i += 1
return crc
def str_to_bytes_pad(string, size):
str_bytes = string.encode()
num_bytes = len(str_bytes)
if (num_bytes >= size):
str_bytes = str_bytes[:size - 1] + '\0'.encode()
else:
str_bytes += '\0'.encode() * (size - num_bytes)
return str_bytes
str_bytes = string.encode()
num_bytes = len(str_bytes)
if num_bytes >= size:
str_bytes = str_bytes[: size - 1] + "\0".encode()
else:
str_bytes += "\0".encode() * (size - num_bytes)
return str_bytes
def create_tag(args, in_bytes, size):
crc = crc32(in_bytes, size, CRC32_INIT)
# JAM CRC32 is bitwise not and unsigned
crc = ~binascii.crc32(in_bytes) & 0xFFFFFFFF
tag = bytearray()
tag += struct.pack('>I', args.part_id)
tag += struct.pack('>I', size)
tag += struct.pack('>H', args.part_flags)
tag += str_to_bytes_pad(args.part_name, PART_NAME_SIZE)
tag += str_to_bytes_pad(args.part_version, PART_VERSION_SIZE)
tag += struct.pack('>I', crc)
tag = bytearray()
tag += struct.pack(">I", args.part_id)
tag += struct.pack(">I", size)
tag += struct.pack(">H", args.part_flags)
tag += str_to_bytes_pad(args.part_name, PART_NAME_SIZE)
tag += str_to_bytes_pad(args.part_version, PART_VERSION_SIZE)
tag += struct.pack(">I", crc)
return tag
return tag
def create_output(args):
in_st = os.stat(args.input_file)
in_size = in_st.st_size
in_st = os.stat(args.input_file)
in_size = in_st.st_size
in_f = open(args.input_file, 'r+b')
in_bytes = in_f.read(in_size)
in_f.close()
in_f = open(args.input_file, "r+b")
in_bytes = in_f.read(in_size)
in_f.close()
tag = create_tag(args, in_bytes, in_size)
tag = create_tag(args, in_bytes, in_size)
out_f = open(args.output_file, "w+b")
out_f.write(tag)
out_f.close()
out_f = open(args.output_file, 'w+b')
out_f.write(tag)
out_f.close()
def main():
global args
global args
parser = argparse.ArgumentParser(description='')
parser = argparse.ArgumentParser(description="")
parser.add_argument('--flags',
dest='part_flags',
action='store',
type=auto_int,
help='Partition Flags')
parser.add_argument(
"--flags",
dest="part_flags",
action="store",
type=auto_int,
help="Partition Flags",
)
parser.add_argument('--id',
dest='part_id',
action='store',
type=auto_int,
help='Partition ID')
parser.add_argument(
"--id",
dest="part_id",
action="store",
type=auto_int,
help="Partition ID",
)
parser.add_argument('--input-file',
dest='input_file',
action='store',
type=str,
help='Input file')
parser.add_argument(
"--input-file",
dest="input_file",
action="store",
type=str,
help="Input file",
)
parser.add_argument('--output-file',
dest='output_file',
action='store',
type=str,
help='Output file')
parser.add_argument(
"--output-file",
dest="output_file",
action="store",
type=str,
help="Output file",
)
parser.add_argument('--name',
dest='part_name',
action='store',
type=str,
help='Partition Name')
parser.add_argument(
"--name",
dest="part_name",
action="store",
type=str,
help="Partition Name",
)
parser.add_argument('--version',
dest='part_version',
action='store',
type=str,
help='Partition Version')
parser.add_argument(
"--version",
dest="part_version",
action="store",
type=str,
help="Partition Version",
)
args = parser.parse_args()
args = parser.parse_args()
if (
(not args.part_flags)
or (not args.part_id)
or (not args.input_file)
or (not args.output_file)
or (not args.part_name)
or (not args.part_version)
):
parser.print_help()
else:
create_output(args)
if ((not args.part_flags) or
(not args.part_id) or
(not args.input_file) or
(not args.output_file) or
(not args.part_name) or
(not args.part_version)):
parser.print_help()
else:
create_output(args)
main()

View File

@ -43,158 +43,107 @@ Flags:
import argparse
import os
import struct
import binascii
CRC32_INIT = 0xFFFFFFFF
CRC32_TABLE = [
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
]
def auto_int(x):
return int(x, 0)
return int(x, 0)
def crc32(bytes, size, crc):
i = 0
while (i < size):
crc = (crc >> 8) ^ CRC32_TABLE[(crc ^ bytes[i]) & 0xff]
i += 1
return crc
def create_tag(args, in_bytes, size):
crc = crc32(in_bytes, size, CRC32_INIT)
tag = struct.pack('>IIIII', crc, args.tag_version, args.chip_id, args.flash_type, args.flags)
return tag
def create_tag(args, in_bytes):
# JAM CRC32 is bitwise not and unsigned
crc = ~binascii.crc32(in_bytes) & 0xFFFFFFFF
tag = struct.pack(
">IIIII",
crc,
args.tag_version,
args.chip_id,
args.flash_type,
args.flags,
)
return tag
def create_output(args):
in_st = os.stat(args.input_file)
in_size = in_st.st_size
in_st = os.stat(args.input_file)
in_size = in_st.st_size
in_f = open(args.input_file, 'r+b')
in_bytes = in_f.read(in_size)
in_f.close()
in_f = open(args.input_file, "r+b")
in_bytes = in_f.read(in_size)
in_f.close()
tag = create_tag(args, in_bytes, in_size)
tag = create_tag(args, in_bytes)
out_f = open(args.output_file, "w+b")
out_f.write(in_bytes)
out_f.write(tag)
out_f.close()
out_f = open(args.output_file, 'w+b')
out_f.write(in_bytes)
out_f.write(tag)
out_f.close()
def main():
global args
global args
parser = argparse.ArgumentParser(description='')
parser = argparse.ArgumentParser(description="")
parser.add_argument('--input-file',
dest='input_file',
action='store',
type=str,
help='Input file')
parser.add_argument(
"--input-file",
dest="input_file",
action="store",
type=str,
help="Input file",
)
parser.add_argument('--output-file',
dest='output_file',
action='store',
type=str,
help='Output file')
parser.add_argument(
"--output-file",
dest="output_file",
action="store",
type=str,
help="Output file",
)
parser.add_argument('--version',
dest='tag_version',
action='store',
type=auto_int,
help='WFI Tag Version')
parser.add_argument(
"--version",
dest="tag_version",
action="store",
type=auto_int,
help="WFI Tag Version",
)
parser.add_argument('--chip-id',
dest='chip_id',
action='store',
type=auto_int,
help='WFI Chip ID')
parser.add_argument(
"--chip-id",
dest="chip_id",
action="store",
type=auto_int,
help="WFI Chip ID",
)
parser.add_argument('--flash-type',
dest='flash_type',
action='store',
type=auto_int,
help='WFI Flash Type')
parser.add_argument(
"--flash-type",
dest="flash_type",
action="store",
type=auto_int,
help="WFI Flash Type",
)
parser.add_argument('--flags',
dest='flags',
action='store',
type=auto_int,
help='WFI Flags')
parser.add_argument(
"--flags", dest="flags", action="store", type=auto_int, help="WFI Flags"
)
args = parser.parse_args()
args = parser.parse_args()
if not args.flags:
args.flags = 0
if not args.flags:
args.flags = 0
if (
(not args.input_file)
or (not args.output_file)
or (not args.tag_version)
or (not args.chip_id)
or (not args.flash_type)
):
parser.print_help()
else:
create_output(args)
if ((not args.input_file) or
(not args.output_file) or
(not args.tag_version) or
(not args.chip_id) or
(not args.flash_type)):
parser.print_help()
else:
create_output(args)
main()

View File

@ -0,0 +1,14 @@
#!/bin/sh
eval "$(grep CONFIG_GCC_VERSION .config)"
CONFIG_TOOLCHAIN_BUILD_VER="$CONFIG_GCC_VERSION-$(cat toolchain/build_version)"
touch .toolchain_build_ver
CURRENT_TOOLCHAIN_BUILD_VER="$(cat .toolchain_build_ver)"
[ -z "$CURRENT_TOOLCHAIN_BUILD_VER" ] && {
echo "$CONFIG_TOOLCHAIN_BUILD_VER" > .toolchain_build_ver
exit 0
}
[ "$CONFIG_TOOLCHAIN_BUILD_VER" = "$CURRENT_TOOLCHAIN_BUILD_VER" ] && exit 0
echo "Toolchain build version changed ($CONFIG_TOOLCHAIN_BUILD_VER != $CURRENT_TOOLCHAIN_BUILD_VER), running make targetclean"
make targetclean
echo "$CONFIG_TOOLCHAIN_BUILD_VER" > .toolchain_build_ver
exit 0

View File

@ -4697,7 +4697,7 @@ sub process {
## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
##
## # Remove any bracketed sections to ensure we do not
## # falsly report the parameters of functions.
## # falsely report the parameters of functions.
## my $ln = $line;
## while ($ln =~ s/\([^\(\)]*\)//g) {
## }

11
scripts/command_all.sh Executable file
View File

@ -0,0 +1,11 @@
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Reduced version of which -a using command utility
case $PATH in
(*[!:]:) PATH="$PATH:" ;;
esac
for ELEMENT in $(echo $PATH | tr ":" "\n"); do
PATH=$ELEMENT command -v "$@"
done

View File

@ -1,22 +1,16 @@
#
# Generated files
#
*.moc
*conf-cfg
# SPDX-License-Identifier: GPL-2.0-only
/conf
/[gmnq]conf
/[gmnq]conf-cfg
/qconf-moc.cc
# From linux kconfig parent directories
.*
# OpenWrt-generated files
mconf_check
#
# configuration programs
#
conf
mconf
nconf
qconf
gconf
#
# temporary files from older version. Should be removed
#
# Temporary files from older versions. They should be removed after the
# end of support for OpenWrt 19.07.
zconf.???.c
zconf.hash.c
.tmp_qtcheck

View File

@ -5,11 +5,11 @@
.PHONY: clean all
all: conf mconf
clean:
rm -f *.o lxdialog/*.o *.moc $(clean-files) conf mconf qconf nconf
rm -f *.o lxdialog/*.o *.moc .*.cmd $(clean-files)
# This clean-files definition is here to ensure that temporary files from the
# previous version are removed by make config-clean.
# It should be removed or emptied when this Makefile get updated again.
# It should be emptied after the end of support for OpenWrt 19.07.
clean-files := zconf.tab.c zconf.lex.c zconf.hash.c .tmp_qtcheck
# ===========================================================================
@ -24,9 +24,11 @@ src:=.
obj:=.
Q:=$(if $V,,@)
cmd = $(cmd_$(1))
dot-target = $(dir $@).$(notdir $@)
# taken from ../Kbuild.include
# some definitions taken from ../Kbuild.include
dot-target = $(dir $@).$(notdir $@)
squote := '
escsq = $(subst $(squote),'\$(squote)',$1)
define filechk
$(Q)set -e; \
mkdir -p $(dir $@); \
@ -37,23 +39,29 @@ define filechk
mv -f $(dot-target).tmp $@; \
fi
endef
cmd-check = $(if $(strip $(cmd_$@)),,1)
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
newer-prereqs = $(filter-out $(PHONY),$?)
if_changed = $(if $(newer-prereqs)$(cmd-check), \
$(cmd); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
### Stripped down upstream Makefile follows:
# ===========================================================================
# object files used by all kconfig flavours
common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \
symbol.o util.o
common-objs := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \
preprocess.o symbol.o util.o
$(obj)/lexer.lex.o: $(obj)/parser.tab.h
HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src)
HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src)
# conf: Used for defconfig, oldconfig and related targets
hostprogs-y += conf
hostprogs += conf
conf-objs := conf.o $(common-objs)
# nconf: Used for the nconfig target based on ncurses
hostprogs-y += nconf
hostprogs += nconf
nconf-objs := nconf.o nconf.gui.o $(common-objs)
HOSTLDLIBS_nconf = $(shell . $(obj)/nconf-cfg && echo $$libs)
@ -63,7 +71,7 @@ HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/nconf-cfg && echo $$cflags)
$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg
# mconf: Used for the menuconfig target based on lxdialog
hostprogs-y += mconf
hostprogs += mconf
lxdialog := $(addprefix lxdialog/, \
checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
mconf-objs := mconf.o $(lxdialog) $(common-objs)
@ -75,20 +83,23 @@ $(foreach f, mconf.o $(lxdialog), \
$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
# qconf: Used for the xconfig target based on Qt
hostprogs-y += qconf
qconf-cxxobjs := qconf.o
hostprogs += qconf
qconf-cxxobjs := qconf.o qconf-moc.o
qconf-objs := images.o $(common-objs)
HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs)
HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
$(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc
$(obj)/qconf.o: $(obj)/qconf-cfg
quiet_cmd_moc = MOC $@
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@
$(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg
$(call cmd,moc)
$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE
$(call if_changed,moc)
targets += qconf-moc.cc
# check if necessary packages are available, and configure build flags
filechk_conf_cfg = $(CONFIG_SHELL) $<
@ -102,6 +113,8 @@ clean-files += *conf-cfg
# OpenWrt rules and final adjustments that need to be made after reading the
# full upstream Makefile
clean-files += $(targets) $(hostprogs)
FORCE:
ifdef BUILD_SHIPPED_FILES
@ -117,24 +130,25 @@ clean-files += $(shipped-files)
flex -L -o$@ $<
endif
$(foreach f, mconf.o $(lxdialog), \
$(eval $f: CFLAGS+=$$(HOSTCFLAGS_$f)))
$(foreach f,$(conf-objs) $(filter-out $(common-objs),$(mconf-objs) \
$(qconf-objs) \
$(nconf-objs)), \
$(eval $(obj)/$f: CFLAGS+=$$(HOSTCFLAGS_$f)))
$(obj)/lexer.lex.o: CFLAGS += $(HOSTCFLAGS_lexer.lex.o)
$(obj)/parser.tab.o: CFLAGS += $(HOSTCFLAGS_parser.tab.o)
$(obj)/qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o)
$(foreach f,$(qconf-cxxobjs), \
$(eval $(obj)/$f: CXXFLAGS+=$$(HOSTCXXFLAGS_$f)))
conf: $(conf-objs)
$(obj)/conf: $(addprefix $(obj)/,$(conf-objs))
# The *conf-cfg file is used (then filtered out) as the first prerequisite to
# avoid sourcing it before the script is built, when trying to compute CFLAGS
# for the actual first prerequisite. This avoids errors like:
# '/bin/sh: ./mconf-cfg: No such file or directory'
mconf: mconf-cfg $(mconf-objs)
$(obj)/mconf: mconf-cfg $(addprefix $(obj)/,$(mconf-objs))
$(CC) -o $@ $(filter-out mconf-cfg,$^) $(HOSTLDLIBS_mconf)
nconf: nconf-cfg $(nconf-objs)
$(obj)/nconf: nconf-cfg $(addprefix $(obj)/,$(nconf-objs))
$(CC) -o $@ $(filter-out nconf-cfg,$^) $(HOSTLDLIBS_nconf)
qconf: qconf-cfg $(qconf-cxxobjs) $(qconf-objs)
$(obj)/qconf: qconf-cfg $(addprefix $(obj)/,$(qconf-cxxobjs) $(qconf-objs))
$(CXX) -o $@ $(filter-out qconf-cfg,$^) $(HOSTLDLIBS_qconf)

View File

@ -1,7 +1,6 @@
These files were taken from the Linux Kernel Configuration System at commit
089b7d890f972f6b649fedc9259f6b93a18fb970 (Feb 4, 2020) and modified for the
OpenWrt Buildroot:
- Removed gconf, tests and kernel configuration targets.
These files were taken from the Linux 5.14 Kernel Configuration System and
modified for the OpenWrt Buildroot:
- Removed nconf, gconf, tests and kernel configuration targets.
- Adjusted the Makefile to compile outside the kernel.
- Always use default file when running make all{no,mod,yes}config.
- Added a 'reset' command to reset config when the target changes.
@ -24,4 +23,4 @@ OpenWrt Buildroot:
BUILD_SHIPPED_FILES defined
For a full list of changes, see the repository at:
https://github.com/cotequeiroz/linux/commits/openwrt/scripts/kconfig
https://github.com/cotequeiroz/linux/commits/openwrt-5.14/scripts/kconfig

View File

@ -11,7 +11,6 @@
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <errno.h>
@ -39,7 +38,7 @@ enum input_mode {
fatalrecursive,
};
static enum input_mode input_mode = oldaskconfig;
static int input_mode_opt;
static int indent = 1;
static int tty_stdio;
static int sync_kconfig;
@ -84,10 +83,243 @@ static void xfgets(char *str, int size, FILE *in)
printf("%s", str);
}
static void set_randconfig_seed(void)
{
unsigned int seed;
char *env;
bool seed_set = false;
env = getenv("KCONFIG_SEED");
if (env && *env) {
char *endp;
seed = strtol(env, &endp, 0);
if (*endp == '\0')
seed_set = true;
}
if (!seed_set) {
struct timeval now;
/*
* Use microseconds derived seed, compensate for systems where it may
* be zero.
*/
gettimeofday(&now, NULL);
seed = (now.tv_sec + 1) * (now.tv_usec + 1);
}
printf("KCONFIG_SEED=0x%X\n", seed);
srand(seed);
}
static bool randomize_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
struct expr *e;
int cnt, def;
/*
* If choice is mod then we may have more items selected
* and if no then no-one.
* In both cases stop.
*/
if (csym->curr.tri != yes)
return false;
prop = sym_get_choice_prop(csym);
/* count entries in choice block */
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym)
cnt++;
/*
* find a random value and set it to yes,
* set the rest to no so we have only one set
*/
def = rand() % cnt;
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym) {
if (def == cnt++) {
sym->def[S_DEF_USER].tri = yes;
csym->def[S_DEF_USER].val = sym;
} else {
sym->def[S_DEF_USER].tri = no;
}
sym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
sym->flags &= ~SYMBOL_VALID;
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~SYMBOL_VALID;
return true;
}
enum conf_def_mode {
def_default,
def_yes,
def_mod,
def_y2m,
def_m2y,
def_no,
def_random
};
static bool conf_set_all_new_symbols(enum conf_def_mode mode)
{
struct symbol *sym, *csym;
int i, cnt;
/*
* can't go as the default in switch-case below, otherwise gcc whines
* about -Wmaybe-uninitialized
*/
int pby = 50; /* probability of bool = y */
int pty = 33; /* probability of tristate = y */
int ptm = 33; /* probability of tristate = m */
bool has_changed = false;
if (mode == def_random) {
int n, p[3];
char *env = getenv("KCONFIG_PROBABILITY");
n = 0;
while (env && *env) {
char *endp;
int tmp = strtol(env, &endp, 10);
if (tmp >= 0 && tmp <= 100) {
p[n++] = tmp;
} else {
errno = ERANGE;
perror("KCONFIG_PROBABILITY");
exit(1);
}
env = (*endp == ':') ? endp + 1 : endp;
if (n >= 3)
break;
}
switch (n) {
case 1:
pby = p[0];
ptm = pby / 2;
pty = pby - ptm;
break;
case 2:
pty = p[0];
ptm = p[1];
pby = pty + ptm;
break;
case 3:
pby = p[0];
pty = p[1];
ptm = p[2];
break;
}
if (pty + ptm > 100) {
errno = ERANGE;
perror("KCONFIG_PROBABILITY");
exit(1);
}
}
sym_clear_all_valid();
for_all_symbols(i, sym) {
if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
continue;
switch (sym_get_type(sym)) {
case S_BOOLEAN:
case S_TRISTATE:
has_changed = true;
switch (mode) {
case def_yes:
sym->def[S_DEF_USER].tri = yes;
break;
case def_mod:
sym->def[S_DEF_USER].tri = mod;
break;
case def_no:
sym->def[S_DEF_USER].tri = no;
break;
case def_random:
sym->def[S_DEF_USER].tri = no;
cnt = rand() % 100;
if (sym->type == S_TRISTATE) {
if (cnt < pty)
sym->def[S_DEF_USER].tri = yes;
else if (cnt < pty + ptm)
sym->def[S_DEF_USER].tri = mod;
} else if (cnt < pby)
sym->def[S_DEF_USER].tri = yes;
break;
default:
continue;
}
if (!(sym_is_choice(sym) && mode == def_random))
sym->flags |= SYMBOL_DEF_USER;
break;
default:
break;
}
}
/*
* We have different type of choice blocks.
* If curr.tri equals to mod then we can select several
* choice symbols in one block.
* In this case we do nothing.
* If curr.tri equals yes then only one symbol can be
* selected in a choice block and we set it to yes,
* and the rest to no.
*/
if (mode != def_random) {
for_all_symbols(i, csym) {
if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
sym_is_choice_value(csym))
csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
}
}
for_all_symbols(i, csym) {
if (sym_has_value(csym) || !sym_is_choice(csym))
continue;
sym_calc_value(csym);
if (mode == def_random)
has_changed |= randomize_choice_values(csym);
else {
set_all_choice_values(csym);
has_changed = true;
}
}
return has_changed;
}
static void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
{
struct symbol *sym;
int i;
tristate old_val = (mode == def_y2m) ? yes : mod;
tristate new_val = (mode == def_y2m) ? mod : yes;
for_all_symbols(i, sym) {
if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val)
sym->def[S_DEF_USER].tri = new_val;
}
sym_clear_all_valid();
}
static int conf_askvalue(struct symbol *sym, const char *def)
{
enum symbol_type type = sym_get_type(sym);
if (!sym_has_value(sym))
printf("(NEW) ");
@ -109,24 +341,12 @@ static int conf_askvalue(struct symbol *sym, const char *def)
return 0;
}
/* fall through */
case oldaskconfig:
default:
fflush(stdout);
xfgets(line, sizeof(line), stdin);
return 1;
default:
break;
}
switch (type) {
case S_INT:
case S_HEX:
case S_STRING:
printf("%s\n", def);
return 1;
default:
;
}
printf("%s", line);
return 1;
}
@ -139,7 +359,7 @@ static int conf_string(struct menu *menu)
printf("%*s%s ", indent - 1, "", menu->prompt->text);
printf("(%s) ", sym->name);
def = sym_get_string_value(sym);
if (sym_get_string_value(sym))
if (def)
printf("[%s] ", def);
if (!conf_askvalue(sym, def))
return 0;
@ -421,34 +641,37 @@ static void check_conf(struct menu *menu)
return;
sym = menu->sym;
if (sym && !sym_has_value(sym)) {
if (sym_is_changeable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (input_mode == listnewconfig) {
if (sym->name) {
const char *str;
if (sym && !sym_has_value(sym) &&
(sym_is_changeable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
if (sym->type == S_STRING) {
str = sym_get_string_value(sym);
str = sym_escape_string_value(str);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
free((void *)str);
} else {
str = sym_get_string_value(sym);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
}
switch (input_mode) {
case listnewconfig:
if (sym->name) {
const char *str;
if (sym->type == S_STRING) {
str = sym_get_string_value(sym);
str = sym_escape_string_value(str);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
free((void *)str);
} else {
str = sym_get_string_value(sym);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
}
} else if (input_mode == helpnewconfig) {
printf("-----\n");
print_help(menu);
printf("-----\n");
} else {
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
break;
case helpnewconfig:
printf("-----\n");
print_help(menu);
printf("-----\n");
break;
default:
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
break;
}
}
@ -456,31 +679,38 @@ static void check_conf(struct menu *menu)
check_conf(child);
}
static struct option long_opts[] = {
{"oldaskconfig", no_argument, NULL, oldaskconfig},
{"oldconfig", no_argument, NULL, oldconfig},
{"syncconfig", no_argument, NULL, syncconfig},
{"defconfig", required_argument, NULL, defconfig},
{"savedefconfig", required_argument, NULL, savedefconfig},
{"allnoconfig", no_argument, NULL, allnoconfig},
{"allyesconfig", no_argument, NULL, allyesconfig},
{"allmodconfig", no_argument, NULL, allmodconfig},
{"alldefconfig", no_argument, NULL, alldefconfig},
{"randconfig", no_argument, NULL, randconfig},
{"listnewconfig", no_argument, NULL, listnewconfig},
{"helpnewconfig", no_argument, NULL, helpnewconfig},
{"olddefconfig", no_argument, NULL, olddefconfig},
{"yes2modconfig", no_argument, NULL, yes2modconfig},
{"mod2yesconfig", no_argument, NULL, mod2yesconfig},
{"fatalrecursive", no_argument, NULL, fatalrecursive},
static const struct option long_opts[] = {
{"help", no_argument, NULL, 'h'},
{"silent", no_argument, NULL, 's'},
{"oldaskconfig", no_argument, &input_mode_opt, oldaskconfig},
{"oldconfig", no_argument, &input_mode_opt, oldconfig},
{"syncconfig", no_argument, &input_mode_opt, syncconfig},
{"defconfig", required_argument, &input_mode_opt, defconfig},
{"savedefconfig", required_argument, &input_mode_opt, savedefconfig},
{"allnoconfig", no_argument, &input_mode_opt, allnoconfig},
{"allyesconfig", no_argument, &input_mode_opt, allyesconfig},
{"allmodconfig", no_argument, &input_mode_opt, allmodconfig},
{"alldefconfig", no_argument, &input_mode_opt, alldefconfig},
{"randconfig", no_argument, &input_mode_opt, randconfig},
{"listnewconfig", no_argument, &input_mode_opt, listnewconfig},
{"helpnewconfig", no_argument, &input_mode_opt, helpnewconfig},
{"olddefconfig", no_argument, &input_mode_opt, olddefconfig},
{"yes2modconfig", no_argument, &input_mode_opt, yes2modconfig},
{"mod2yesconfig", no_argument, &input_mode_opt, mod2yesconfig},
{"fatalrecursive",no_argument, NULL, fatalrecursive},
{NULL, 0, NULL, 0}
};
static void conf_usage(const char *progname)
{
printf("Usage: %s [-s] [--fatalrecursive] [option] <kconfig-file>\n", progname);
printf("[option] is _one_ of the following:\n");
printf("Usage: %s [options] <kconfig-file>\n", progname);
printf("\n");
printf("Generic options:\n");
printf(" -h, --help Print this message and exit.\n");
printf(" -s, --silent Do not print log.\n");
printf(" --fatalrecursive Treat recursive depenendencies as a fatal error\n");
printf("\n");
printf("Mode options:\n");
printf(" --listnewconfig List new options\n");
printf(" --helpnewconfig List new options and help text\n");
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
@ -497,6 +727,7 @@ static void conf_usage(const char *progname)
printf(" --randconfig New config with random answer to all options\n");
printf(" --yes2modconfig Change answers from yes to mod if possible\n");
printf(" --mod2yesconfig Change answers from mod to yes if possible\n");
printf(" (If none of the above is given, --oldaskconfig is the default)\n");
}
int main(int ac, char **av)
@ -509,84 +740,56 @@ int main(int ac, char **av)
tty_stdio = isatty(0) && isatty(1);
while ((opt = getopt_long(ac, av, "r:w:s", long_opts, NULL)) != -1) {
if (opt == 's') {
conf_set_message_callback(NULL);
continue;
}
while ((opt = getopt_long(ac, av, "hr:sw:", long_opts, NULL)) != -1) {
switch (opt) {
case syncconfig:
/*
* syncconfig is invoked during the build stage.
* Suppress distracting "configuration written to ..."
*/
case 'h':
conf_usage(progname);
exit(1);
break;
case 's':
conf_set_message_callback(NULL);
sync_kconfig = 1;
break;
case defconfig:
case savedefconfig:
defconfig_file = optarg;
break;
case randconfig:
{
struct timeval now;
unsigned int seed;
char *seed_env;
/*
* Use microseconds derived seed,
* compensate for systems where it may be zero
*/
gettimeofday(&now, NULL);
seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
seed_env = getenv("KCONFIG_SEED");
if( seed_env && *seed_env ) {
char *endp;
int tmp = (int)strtol(seed_env, &endp, 0);
if (*endp == '\0') {
seed = tmp;
}
}
fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
srand(seed);
break;
}
case oldaskconfig:
case oldconfig:
case allnoconfig:
case allyesconfig:
case allmodconfig:
case alldefconfig:
case listnewconfig:
case helpnewconfig:
case olddefconfig:
case yes2modconfig:
case mod2yesconfig:
break;
case fatalrecursive:
recursive_is_error = 1;
continue;
case 'r':
input_file = optarg;
continue;
break;
case 'w':
output_file = optarg;
continue;
case '?':
conf_usage(progname);
exit(1);
break;
case 0:
input_mode = input_mode_opt;
switch (input_mode) {
case syncconfig:
/*
* syncconfig is invoked during the build stage.
* Suppress distracting
* "configuration written to ..."
*/
conf_set_message_callback(NULL);
sync_kconfig = 1;
break;
case defconfig:
case savedefconfig:
defconfig_file = optarg;
break;
case randconfig:
set_randconfig_seed();
break;
default:
break;
}
default:
break;
}
input_mode = (enum input_mode)opt;
}
if (ac == optind) {
fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
conf_usage(progname);
exit(1);
}
name = av[optind];
conf_parse(name);
conf_parse(av[optind]);
//zconfdump(stdout);
switch (input_mode) {

View File

@ -5,6 +5,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@ -32,7 +33,7 @@ static bool is_dir(const char *path)
struct stat st;
if (stat(path, &st))
return 0;
return false;
return S_ISDIR(st.st_mode);
}
@ -129,19 +130,14 @@ static size_t depfile_prefix_len;
static int conf_touch_dep(const char *name)
{
int fd, ret;
const char *s;
char *d, c;
char *d;
/* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */
if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path))
/* check overflow: prefix + name + '\0' must fit in buffer. */
if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
return -1;
d = depfile_path + depfile_prefix_len;
s = name;
while ((c = *s++))
*d++ = (c == '_') ? '/' : tolower(c);
strcpy(d, ".h");
strcpy(d, name);
/* Assume directory path already exists. */
fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@ -384,28 +380,46 @@ int conf_read_simple(const char *name, int def)
if (name) {
in = zconf_fopen(name);
} else {
struct property *prop;
char *env;
name = conf_get_configname();
in = zconf_fopen(name);
if (in)
goto load;
sym_add_change_count(1);
if (!sym_defconfig_list)
conf_set_changed(true);
env = getenv("KCONFIG_DEFCONFIG_LIST");
if (!env)
return 1;
for_all_defaults(sym_defconfig_list, prop) {
if (expr_calc_value(prop->visible.expr) == no ||
prop->expr->type != E_SYMBOL)
continue;
sym_calc_value(prop->expr->left.sym);
name = sym_get_string_value(prop->expr->left.sym);
in = zconf_fopen(name);
while (1) {
bool is_last;
while (isspace(*env))
env++;
if (!*env)
break;
p = env;
while (*p && !isspace(*p))
p++;
is_last = (*p == '\0');
*p = '\0';
in = zconf_fopen(env);
if (in) {
conf_message("using defaults found in %s",
name);
env);
goto load;
}
if (is_last)
break;
env = p + 1;
}
}
if (!in)
@ -434,7 +448,7 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
sym_add_change_count(1);
conf_set_changed(true);
continue;
}
} else {
@ -470,11 +484,11 @@ load:
* Reading from include/config/auto.conf
* If CONFIG_FOO previously existed in
* auto.conf but it is missing now,
* include/config/foo.h must be touched.
* include/config/FOO must be touched.
*/
conf_touch_dep(line + strlen(CONFIG_));
else
sym_add_change_count(1);
conf_set_changed(true);
continue;
}
@ -519,7 +533,7 @@ int conf_read(const char *name)
int conf_unsaved = 0;
int i;
sym_set_change_count(0);
conf_set_changed(false);
if (conf_read_simple(name, S_DEF_USER)) {
sym_calc_value(modules_sym);
@ -577,7 +591,8 @@ int conf_read(const char *name)
}
}
sym_add_change_count(conf_warnings || conf_unsaved);
if (conf_warnings || conf_unsaved)
conf_set_changed(true);
return 0;
}
@ -922,7 +937,7 @@ next:
if (is_same(name, tmpname)) {
conf_message("No change to %s", name);
unlink(tmpname);
sym_set_change_count(0);
conf_set_changed(false);
return 0;
}
@ -934,7 +949,7 @@ next:
conf_message("configuration written to %s", name);
sym_set_change_count(0);
conf_set_changed(false);
return 0;
}
@ -1105,26 +1120,20 @@ int conf_write_autoconf(int overwrite)
return 0;
}
static int sym_change_count;
static bool conf_changed;
static void (*conf_changed_callback)(void);
void sym_set_change_count(int count)
void conf_set_changed(bool val)
{
int _sym_change_count = sym_change_count;
sym_change_count = count;
if (conf_changed_callback &&
(bool)_sym_change_count != (bool)count)
if (conf_changed_callback && conf_changed != val)
conf_changed_callback();
}
void sym_add_change_count(int count)
{
sym_set_change_count(count + sym_change_count);
conf_changed = val;
}
bool conf_get_changed(void)
{
return sym_change_count;
return conf_changed;
}
void conf_set_changed_callback(void (*fn)(void))
@ -1132,54 +1141,6 @@ void conf_set_changed_callback(void (*fn)(void))
conf_changed_callback = fn;
}
static bool randomize_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
struct expr *e;
int cnt, def;
/*
* If choice is mod then we may have more items selected
* and if no then no-one.
* In both cases stop.
*/
if (csym->curr.tri != yes)
return false;
prop = sym_get_choice_prop(csym);
/* count entries in choice block */
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym)
cnt++;
/*
* find a random value and set it to yes,
* set the rest to no so we have only one set
*/
def = (rand() % cnt);
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym) {
if (def == cnt++) {
sym->def[S_DEF_USER].tri = yes;
csym->def[S_DEF_USER].val = sym;
}
else {
sym->def[S_DEF_USER].tri = no;
}
sym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
sym->flags &= ~SYMBOL_VALID;
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
return true;
}
void set_all_choice_values(struct symbol *csym)
{
struct property *prop;
@ -1199,147 +1160,3 @@ void set_all_choice_values(struct symbol *csym)
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
}
bool conf_set_all_new_symbols(enum conf_def_mode mode)
{
struct symbol *sym, *csym;
int i, cnt, pby, pty, ptm; /* pby: probability of bool = y
* pty: probability of tristate = y
* ptm: probability of tristate = m
*/
pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
* below, otherwise gcc whines about
* -Wmaybe-uninitialized */
if (mode == def_random) {
int n, p[3];
char *env = getenv("KCONFIG_PROBABILITY");
n = 0;
while( env && *env ) {
char *endp;
int tmp = strtol( env, &endp, 10 );
if( tmp >= 0 && tmp <= 100 ) {
p[n++] = tmp;
} else {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
env = (*endp == ':') ? endp+1 : endp;
if( n >=3 ) {
break;
}
}
switch( n ) {
case 1:
pby = p[0]; ptm = pby/2; pty = pby-ptm;
break;
case 2:
pty = p[0]; ptm = p[1]; pby = pty + ptm;
break;
case 3:
pby = p[0]; pty = p[1]; ptm = p[2];
break;
}
if( pty+ptm > 100 ) {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
}
bool has_changed = false;
sym_clear_all_valid();
for_all_symbols(i, sym) {
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
continue;
switch (sym_get_type(sym)) {
case S_BOOLEAN:
case S_TRISTATE:
has_changed = true;
switch (mode) {
case def_yes:
sym->def[S_DEF_USER].tri = yes;
break;
case def_mod:
sym->def[S_DEF_USER].tri = mod;
break;
case def_no:
if (sym->flags & SYMBOL_ALLNOCONFIG_Y)
sym->def[S_DEF_USER].tri = yes;
else
sym->def[S_DEF_USER].tri = no;
break;
case def_random:
sym->def[S_DEF_USER].tri = no;
cnt = rand() % 100;
if (sym->type == S_TRISTATE) {
if (cnt < pty)
sym->def[S_DEF_USER].tri = yes;
else if (cnt < (pty+ptm))
sym->def[S_DEF_USER].tri = mod;
} else if (cnt < pby)
sym->def[S_DEF_USER].tri = yes;
break;
default:
continue;
}
if (!(sym_is_choice(sym) && mode == def_random))
sym->flags |= SYMBOL_DEF_USER;
break;
default:
break;
}
}
/*
* We have different type of choice blocks.
* If curr.tri equals to mod then we can select several
* choice symbols in one block.
* In this case we do nothing.
* If curr.tri equals yes then only one symbol can be
* selected in a choice block and we set it to yes,
* and the rest to no.
*/
if (mode != def_random) {
for_all_symbols(i, csym) {
if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
sym_is_choice_value(csym))
csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
}
}
for_all_symbols(i, csym) {
if (sym_has_value(csym) || !sym_is_choice(csym))
continue;
sym_calc_value(csym);
if (mode == def_random)
has_changed = randomize_choice_values(csym);
else {
set_all_choice_values(csym);
has_changed = true;
}
}
return has_changed;
}
void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
{
struct symbol *sym;
int i;
tristate old_val = (mode == def_y2m) ? yes : mod;
tristate new_val = (mode == def_y2m) ? mod : yes;
for_all_symbols(i, sym) {
if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val) {
sym->def[S_DEF_USER].tri = new_val;
sym_add_change_count(1);
}
}
}

View File

@ -156,9 +156,6 @@ struct symbol {
/* choice values need to be set before calculating this symbol value */
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
/* Set symbol to y if allnoconfig; used for symbols that hide others */
#define SYMBOL_ALLNOCONFIG_Y 0x200000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 9973
@ -282,15 +279,12 @@ struct jump_key {
int index;
};
#define JUMP_NB 9
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
extern struct symbol *sym_defconfig_list;
extern int cdebug;
struct expr *expr_alloc_symbol(struct symbol *sym);
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);

View File

@ -5,7 +5,7 @@
#include "images.h"
const char *xpm_load[] = {
const char * const xpm_load[] = {
"22 22 5 1",
". c None",
"# c #000000",
@ -35,7 +35,7 @@ const char *xpm_load[] = {
"###############.......",
"......................"};
const char *xpm_save[] = {
const char * const xpm_save[] = {
"22 22 5 1",
". c None",
"# c #000000",
@ -65,7 +65,7 @@ const char *xpm_save[] = {
"..##################..",
"......................"};
const char *xpm_back[] = {
const char * const xpm_back[] = {
"22 22 3 1",
". c None",
"# c #000083",
@ -93,7 +93,7 @@ const char *xpm_back[] = {
"......................",
"......................"};
const char *xpm_tree_view[] = {
const char * const xpm_tree_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -120,7 +120,7 @@ const char *xpm_tree_view[] = {
"......................",
"......................"};
const char *xpm_single_view[] = {
const char * const xpm_single_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -147,7 +147,7 @@ const char *xpm_single_view[] = {
"......................",
"......................"};
const char *xpm_split_view[] = {
const char * const xpm_split_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -174,7 +174,7 @@ const char *xpm_split_view[] = {
"......................",
"......................"};
const char *xpm_symbol_no[] = {
const char * const xpm_symbol_no[] = {
"12 12 2 1",
" c white",
". c black",
@ -191,7 +191,7 @@ const char *xpm_symbol_no[] = {
" .......... ",
" "};
const char *xpm_symbol_mod[] = {
const char * const xpm_symbol_mod[] = {
"12 12 2 1",
" c white",
". c black",
@ -208,7 +208,7 @@ const char *xpm_symbol_mod[] = {
" .......... ",
" "};
const char *xpm_symbol_yes[] = {
const char * const xpm_symbol_yes[] = {
"12 12 2 1",
" c white",
". c black",
@ -225,7 +225,7 @@ const char *xpm_symbol_yes[] = {
" .......... ",
" "};
const char *xpm_choice_no[] = {
const char * const xpm_choice_no[] = {
"12 12 2 1",
" c white",
". c black",
@ -242,7 +242,7 @@ const char *xpm_choice_no[] = {
" .... ",
" "};
const char *xpm_choice_yes[] = {
const char * const xpm_choice_yes[] = {
"12 12 2 1",
" c white",
". c black",
@ -259,7 +259,7 @@ const char *xpm_choice_yes[] = {
" .... ",
" "};
const char *xpm_menu[] = {
const char * const xpm_menu[] = {
"12 12 2 1",
" c white",
". c black",
@ -276,7 +276,7 @@ const char *xpm_menu[] = {
" .......... ",
" "};
const char *xpm_menu_inv[] = {
const char * const xpm_menu_inv[] = {
"12 12 2 1",
" c white",
". c black",
@ -293,7 +293,7 @@ const char *xpm_menu_inv[] = {
" .......... ",
" "};
const char *xpm_menuback[] = {
const char * const xpm_menuback[] = {
"12 12 2 1",
" c white",
". c black",
@ -310,7 +310,7 @@ const char *xpm_menuback[] = {
" .......... ",
" "};
const char *xpm_void[] = {
const char * const xpm_void[] = {
"12 12 2 1",
" c white",
". c black",

View File

@ -10,21 +10,21 @@
extern "C" {
#endif
extern const char *xpm_load[];
extern const char *xpm_save[];
extern const char *xpm_back[];
extern const char *xpm_tree_view[];
extern const char *xpm_single_view[];
extern const char *xpm_split_view[];
extern const char *xpm_symbol_no[];
extern const char *xpm_symbol_mod[];
extern const char *xpm_symbol_yes[];
extern const char *xpm_choice_no[];
extern const char *xpm_choice_yes[];
extern const char *xpm_menu[];
extern const char *xpm_menu_inv[];
extern const char *xpm_menuback[];
extern const char *xpm_void[];
extern const char * const xpm_load[];
extern const char * const xpm_save[];
extern const char * const xpm_back[];
extern const char * const xpm_tree_view[];
extern const char * const xpm_single_view[];
extern const char * const xpm_split_view[];
extern const char * const xpm_symbol_no[];
extern const char * const xpm_symbol_mod[];
extern const char * const xpm_symbol_yes[];
extern const char * const xpm_choice_no[];
extern const char * const xpm_choice_yes[];
extern const char * const xpm_menu[];
extern const char * const xpm_menu_inv[];
extern const char * const xpm_menuback[];
extern const char * const xpm_void[];
#ifdef __cplusplus
}

View File

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef INTERNAL_H
#define INTERNAL_H
struct menu;
extern struct menu *current_menu, *current_entry;
#endif /* INTERNAL_H */

View File

@ -12,7 +12,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <glob.h>
#include <libgen.h>
@ -38,7 +37,7 @@ struct buffer {
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
static struct buffer *current_buf;
static int last_ts, first_ts;
@ -94,7 +93,6 @@ n [A-Za-z0-9_-]
[ \t]* /* whitespaces */
\\\n /* escaped new line */
\n return T_EOL;
"allnoconfig_y" return T_ALLNOCONFIG_Y;
"bool" return T_BOOL;
"choice" return T_CHOICE;
"comment" return T_COMMENT;
@ -102,12 +100,11 @@ n [A-Za-z0-9_-]
"def_bool" return T_DEF_BOOL;
"def_tristate" return T_DEF_TRISTATE;
"default" return T_DEFAULT;
"defconfig_list" return T_DEFCONFIG_LIST;
"depends" return T_DEPENDS;
"endchoice" return T_ENDCHOICE;
"endif" return T_ENDIF;
"endmenu" return T_ENDMENU;
"help"|"---help---" return T_HELP;
"help" return T_HELP;
"hex" return T_HEX;
"if" return T_IF;
"imply" return T_IMPLY;
@ -117,7 +114,6 @@ n [A-Za-z0-9_-]
"menuconfig" return T_MENUCONFIG;
"modules" return T_MODULES;
"on" return T_ON;
"option" return T_OPTION;
"optional" return T_OPTIONAL;
"prompt" return T_PROMPT;
"range" return T_RANGE;

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,10 @@
#ifndef LKC_H
#define LKC_H
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "expr.h"
#ifdef __cplusplus
@ -16,10 +20,6 @@ extern "C" {
#define SRCTREE "srctree"
#ifndef PACKAGE
#define PACKAGE "linux"
#endif
#ifndef CONFIG_
#define CONFIG_ "CONFIG_"
#endif
@ -30,16 +30,6 @@ static inline const char *CONFIG_prefix(void)
#undef CONFIG_
#define CONFIG_ CONFIG_prefix()
enum conf_def_mode {
def_default,
def_yes,
def_mod,
def_y2m,
def_m2y,
def_no,
def_random
};
extern int yylineno;
void zconfdump(FILE *out);
void zconf_starthelp(void);
@ -52,10 +42,6 @@ extern int recursive_is_error;
/* confdata.c */
const char *conf_get_configname(void);
void sym_set_change_count(int count);
void sym_add_change_count(int count);
bool conf_set_all_new_symbols(enum conf_def_mode mode);
void conf_rewrite_mod_or_yes(enum conf_def_mode mode);
void set_all_choice_values(struct symbol *csym);
/* confdata.c and expr.c */
@ -67,24 +53,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
fprintf(stderr, "Error in writing or end of file.\n");
}
/* menu.c */
void _menu_init(void);
void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_add_dep(struct expr *dep);
void menu_add_visibility(struct expr *dep);
struct property *menu_add_prop(enum prop_type type, struct expr *expr, struct expr *dep);
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_add_option_modules(void);
void menu_add_option_defconfig_list(void);
void menu_add_option_allnoconfig_y(void);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
/* util.c */
struct file *file_lookup(const char *name);
void *xmalloc(size_t size);
@ -111,6 +79,34 @@ void str_append(struct gstr *gs, const char *s);
void str_printf(struct gstr *gs, const char *fmt, ...);
const char *str_get(struct gstr *gs);
/* menu.c */
void _menu_init(void);
void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_add_dep(struct expr *dep);
void menu_add_visibility(struct expr *dep);
struct property *menu_add_prop(enum prop_type type, struct expr *expr, struct expr *dep);
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
extern struct menu rootmenu;
bool menu_is_empty(struct menu *menu);
bool menu_is_visible(struct menu *menu);
bool menu_has_prompt(struct menu *menu);
const char *menu_get_prompt(struct menu *menu);
struct menu *menu_get_root_menu(struct menu *menu);
struct menu *menu_get_parent_menu(struct menu *menu);
bool menu_has_help(struct menu *menu);
const char *menu_get_help(struct menu *menu);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */
void sym_clear_all_valid(void);
struct symbol *sym_choice_default(struct symbol *sym);

View File

@ -9,24 +9,11 @@ void conf_reset(int def);
int conf_write_defconfig(const char *name);
int conf_write(const char *name);
int conf_write_autoconf(int overwrite);
void conf_set_changed(bool val);
bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(void));
void conf_set_message_callback(void (*fn)(const char *s));
/* menu.c */
extern struct menu rootmenu;
bool menu_is_empty(struct menu *menu);
bool menu_is_visible(struct menu *menu);
bool menu_has_prompt(struct menu *menu);
const char * menu_get_prompt(struct menu *menu);
struct menu * menu_get_root_menu(struct menu *menu);
struct menu * menu_get_parent_menu(struct menu *menu);
bool menu_has_help(struct menu *menu);
const char * menu_get_help(struct menu *menu);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];

View File

@ -363,7 +363,7 @@ void print_title(WINDOW *dialog, const char *title, int width)
/*
* Print a string of text in a window, automatically wrap around to the
* next line if the string is too long to fit on one line. Newline
* characters '\n' are propperly processed. We start on a new line
* characters '\n' are properly processed. We start on a new line
* if there is no room for at least 4 nonblanks following a double-space.
*/
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
@ -541,7 +541,7 @@ int first_alpha(const char *string, const char *exempt)
* lxdialog suggest <ESC> <ESC> which is correctly translated to two
* times esc. But then we need to ignore the second esc to avoid stepping
* out one menu too much. Filter away all escaped key sequences since
* keypad(FALSE) turn off ncurses support for escape sequences - and thats
* keypad(FALSE) turn off ncurses support for escape sequences - and that's
* needed to make notimeout() do as expected.
*/
int on_key_esc(WINDOW *win)

View File

@ -33,7 +33,9 @@ if [ -f /usr/include/ncurses/ncurses.h ]; then
exit 0
fi
if [ -f /usr/include/ncurses.h ]; then
# As a final fallback before giving up, check if $HOSTCC knows of a default
# ncurses installation (e.g. from a vendor-specific sysroot).
if echo '#include <ncurses.h>' | ${HOSTCC} -E - >/dev/null 2>&1; then
echo cflags=\"-D_GNU_SOURCE\"
echo libs=\"-lncurses\"
exit 0

View File

@ -22,6 +22,8 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
#define JUMP_NB 9
static const char mconf_readme[] =
"OpenWrt config is based on Kernel kconfig\n"
"so ipkg packages are referred here as modules.\n"
@ -300,17 +302,12 @@ static char filename[PATH_MAX+1];
static void set_config_filename(const char *config_filename)
{
static char menu_backtitle[PATH_MAX+128];
int size;
size = snprintf(menu_backtitle, sizeof(menu_backtitle),
"%s - %s", config_filename, rootmenu.prompt->text);
if (size >= sizeof(menu_backtitle))
menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s",
config_filename, rootmenu.prompt->text);
set_dialog_backtitle(menu_backtitle);
size = snprintf(filename, sizeof(filename), "%s", config_filename);
if (size >= sizeof(filename))
filename[sizeof(filename)-1] = '\0';
snprintf(filename, sizeof(filename), "%s", config_filename);
}
struct subtitle_part {
@ -921,7 +918,7 @@ static void conf_load(void)
return;
if (!conf_read(dialog_input_result)) {
set_config_filename(dialog_input_result);
sym_set_change_count(1);
conf_set_changed(true);
return;
}
show_textbox(NULL, "File does not exist!", 5, 38);

View File

@ -9,6 +9,7 @@
#include <string.h>
#include "lkc.h"
#include "internal.h"
static const char nohelp_text[] = "There is no help available for this option.";
@ -65,7 +66,8 @@ void menu_add_entry(struct symbol *sym)
struct menu *menu_add_menu(void)
{
last_entry_ptr = &current_entry->list;
return current_menu = current_entry;
current_menu = current_entry;
return current_menu;
}
void menu_end_menu(void)
@ -210,28 +212,6 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, expr_alloc_symbol(sym), dep);
}
void menu_add_option_modules(void)
{
if (modules_sym)
zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'",
current_entry->sym->name, modules_sym->name);
modules_sym = current_entry->sym;
}
void menu_add_option_defconfig_list(void)
{
if (!sym_defconfig_list)
sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol");
sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
}
void menu_add_option_allnoconfig_y(void)
{
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
}
static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
{
return sym2->type == S_INT || sym2->type == S_HEX ||

View File

@ -271,7 +271,7 @@ static int mwin_max_cols;
static MENU *curses_menu;
static ITEM *curses_menu_items[MAX_MENU_ITEMS];
static struct mitem k_menu_items[MAX_MENU_ITEMS];
static int items_num;
static unsigned int items_num;
static int global_exit;
/* the currently selected button */
static const char *current_instructions = menu_instructions;
@ -373,18 +373,18 @@ static void print_function_line(void)
int lines = getmaxy(stdscr);
for (i = 0; i < function_keys_num; i++) {
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
wattrset(main_window, attr_function_highlight);
mvwprintw(main_window, lines-3, offset,
"%s",
function_keys[i].key_str);
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
wattrset(main_window, attr_function_text);
offset += strlen(function_keys[i].key_str);
mvwprintw(main_window, lines-3,
offset, "%s",
function_keys[i].func);
offset += strlen(function_keys[i].func) + skip;
}
(void) wattrset(main_window, attributes[NORMAL]);
wattrset(main_window, attr_normal);
}
/* help */
@ -499,16 +499,20 @@ typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
/* return the index of the matched item, or -1 if no such item exists */
static int get_mext_match(const char *match_str, match_f flag)
{
int match_start = item_index(current_item(curses_menu));
int index;
int match_start, index;
/* Do not search if the menu is empty (i.e. items_num == 0) */
match_start = item_index(current_item(curses_menu));
if (match_start == ERR)
return -1;
if (flag == FIND_NEXT_MATCH_DOWN)
++match_start;
else if (flag == FIND_NEXT_MATCH_UP)
--match_start;
match_start = (match_start + items_num) % items_num;
index = match_start;
index = (index + items_num) % items_num;
while (true) {
char *str = k_menu_items[index].str;
if (strcasestr(str, match_str) != NULL)
@ -630,19 +634,12 @@ static int item_is_tag(char tag)
static char filename[PATH_MAX+1];
static char menu_backtitle[PATH_MAX+128];
static const char *set_config_filename(const char *config_filename)
static void set_config_filename(const char *config_filename)
{
int size;
snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s",
config_filename, rootmenu.prompt->text);
size = snprintf(menu_backtitle, sizeof(menu_backtitle),
"%s - %s", config_filename, rootmenu.prompt->text);
if (size >= sizeof(menu_backtitle))
menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
size = snprintf(filename, sizeof(filename), "%s", config_filename);
if (size >= sizeof(filename))
filename[sizeof(filename)-1] = '\0';
return menu_backtitle;
snprintf(filename, sizeof(filename), "%s", config_filename);
}
/* return = 0 means we are successful.
@ -758,7 +755,6 @@ static void build_conf(struct menu *menu)
switch (ptype) {
case P_MENU:
child_count++;
prompt = prompt;
if (single_menu_mode) {
item_make(menu, 'm',
"%s%*c%s",
@ -960,16 +956,15 @@ static void show_menu(const char *prompt, const char *instructions,
current_instructions = instructions;
clear();
(void) wattrset(main_window, attributes[NORMAL]);
print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
print_in_middle(stdscr, 1, getmaxx(stdscr),
menu_backtitle,
attributes[MAIN_HEADING]);
attr_main_heading);
(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
wattrset(main_window, attr_main_menu_box);
box(main_window, 0, 0);
(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
wattrset(main_window, attr_main_menu_heading);
mvwprintw(main_window, 0, 3, " %s ", prompt);
(void) wattrset(main_window, attributes[NORMAL]);
wattrset(main_window, attr_normal);
set_menu_items(curses_menu, curses_menu_items);
@ -1072,7 +1067,6 @@ static int do_match(int key, struct match_state *state, int *ans)
static void conf(struct menu *menu)
{
struct menu *submenu = NULL;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
int res;
int current_index = 0;
@ -1090,9 +1084,8 @@ static void conf(struct menu *menu)
if (!child_count)
break;
show_menu(prompt ? prompt : "Main Menu",
menu_instructions,
current_index, &last_top_row);
show_menu(menu_get_prompt(menu), menu_instructions,
current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE);
while (!global_exit) {
if (match_state.in_search) {
@ -1418,7 +1411,7 @@ static void conf_load(void)
return;
if (!conf_read(dialog_input_result)) {
set_config_filename(dialog_input_result);
sym_set_change_count(1);
conf_set_changed(true);
return;
}
btn_dialog(main_window, "File does not exist!", 0);
@ -1537,9 +1530,9 @@ int main(int ac, char **av)
menu_opts_on(curses_menu, O_NONCYCLIC);
menu_opts_on(curses_menu, O_IGNORECASE);
set_menu_mark(curses_menu, " ");
set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
set_menu_fore(curses_menu, attr_main_menu_fore);
set_menu_back(curses_menu, attr_main_menu_back);
set_menu_grey(curses_menu, attr_main_menu_grey);
set_config_filename(conf_get_configname());
setup_windows();

View File

@ -7,169 +7,120 @@
#include "nconf.h"
#include "lkc.h"
/* a list of all the different widgets we use */
attributes_t attributes[ATTR_MAX+1] = {0};
int attr_normal;
int attr_main_heading;
int attr_main_menu_box;
int attr_main_menu_fore;
int attr_main_menu_back;
int attr_main_menu_grey;
int attr_main_menu_heading;
int attr_scrollwin_text;
int attr_scrollwin_heading;
int attr_scrollwin_box;
int attr_dialog_text;
int attr_dialog_menu_fore;
int attr_dialog_menu_back;
int attr_dialog_box;
int attr_input_box;
int attr_input_heading;
int attr_input_text;
int attr_input_field;
int attr_function_text;
int attr_function_highlight;
/* available colors:
COLOR_BLACK 0
COLOR_RED 1
COLOR_GREEN 2
COLOR_YELLOW 3
COLOR_BLUE 4
COLOR_MAGENTA 5
COLOR_CYAN 6
COLOR_WHITE 7
*/
static void set_normal_colors(void)
{
init_pair(NORMAL, -1, -1);
init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
#define COLOR_ATTR(_at, _fg, _bg, _hl) \
{ .attr = &(_at), .has_color = true, .color_fg = _fg, .color_bg = _bg, .highlight = _hl }
#define NO_COLOR_ATTR(_at, _hl) \
{ .attr = &(_at), .has_color = false, .highlight = _hl }
#define COLOR_DEFAULT -1
/* FORE is for the selected item */
init_pair(MAIN_MENU_FORE, -1, -1);
/* BACK for all the rest */
init_pair(MAIN_MENU_BACK, -1, -1);
init_pair(MAIN_MENU_GREY, -1, -1);
init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
struct nconf_attr_param {
int *attr;
bool has_color;
int color_fg;
int color_bg;
int highlight;
};
init_pair(SCROLLWIN_TEXT, -1, -1);
init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
static const struct nconf_attr_param color_theme_params[] = {
COLOR_ATTR(attr_normal, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_main_heading, COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD | A_UNDERLINE),
COLOR_ATTR(attr_main_menu_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_main_menu_fore, COLOR_DEFAULT, COLOR_DEFAULT, A_REVERSE),
COLOR_ATTR(attr_main_menu_back, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_main_menu_grey, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_main_menu_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_scrollwin_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_scrollwin_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_scrollwin_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_dialog_text, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_dialog_menu_fore, COLOR_RED, COLOR_DEFAULT, A_STANDOUT),
COLOR_ATTR(attr_dialog_menu_back, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_dialog_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_input_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_input_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD),
COLOR_ATTR(attr_input_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
COLOR_ATTR(attr_input_field, COLOR_DEFAULT, COLOR_DEFAULT, A_UNDERLINE),
COLOR_ATTR(attr_function_text, COLOR_YELLOW, COLOR_DEFAULT, A_REVERSE),
COLOR_ATTR(attr_function_highlight, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD),
{ /* sentinel */ }
};
init_pair(DIALOG_TEXT, -1, -1);
init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
init_pair(INPUT_BOX, COLOR_YELLOW, -1);
init_pair(INPUT_HEADING, COLOR_GREEN, -1);
init_pair(INPUT_TEXT, -1, -1);
init_pair(INPUT_FIELD, -1, -1);
init_pair(FUNCTION_HIGHLIGHT, -1, -1);
init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1);
}
/* available attributes:
A_NORMAL Normal display (no highlight)
A_STANDOUT Best highlighting mode of the terminal.
A_UNDERLINE Underlining
A_REVERSE Reverse video
A_BLINK Blinking
A_DIM Half bright
A_BOLD Extra bright or bold
A_PROTECT Protected mode
A_INVIS Invisible or blank mode
A_ALTCHARSET Alternate character set
A_CHARTEXT Bit-mask to extract a character
COLOR_PAIR(n) Color-pair number n
*/
static void normal_color_theme(void)
{
/* automatically add color... */
#define mkattr(name, attr) do { \
attributes[name] = attr | COLOR_PAIR(name); } while (0)
mkattr(NORMAL, NORMAL);
mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
mkattr(MAIN_MENU_FORE, A_REVERSE);
mkattr(MAIN_MENU_BACK, A_NORMAL);
mkattr(MAIN_MENU_GREY, A_NORMAL);
mkattr(MAIN_MENU_HEADING, A_BOLD);
mkattr(MAIN_MENU_BOX, A_NORMAL);
mkattr(SCROLLWIN_TEXT, A_NORMAL);
mkattr(SCROLLWIN_HEADING, A_BOLD);
mkattr(SCROLLWIN_BOX, A_BOLD);
mkattr(DIALOG_TEXT, A_BOLD);
mkattr(DIALOG_BOX, A_BOLD);
mkattr(DIALOG_MENU_FORE, A_STANDOUT);
mkattr(DIALOG_MENU_BACK, A_NORMAL);
mkattr(INPUT_BOX, A_NORMAL);
mkattr(INPUT_HEADING, A_BOLD);
mkattr(INPUT_TEXT, A_NORMAL);
mkattr(INPUT_FIELD, A_UNDERLINE);
mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
mkattr(FUNCTION_TEXT, A_REVERSE);
}
static void no_colors_theme(void)
{
/* automatically add highlight, no color */
#define mkattrn(name, attr) { attributes[name] = attr; }
mkattrn(NORMAL, NORMAL);
mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
mkattrn(MAIN_MENU_FORE, A_STANDOUT);
mkattrn(MAIN_MENU_BACK, A_NORMAL);
mkattrn(MAIN_MENU_GREY, A_NORMAL);
mkattrn(MAIN_MENU_HEADING, A_BOLD);
mkattrn(MAIN_MENU_BOX, A_NORMAL);
mkattrn(SCROLLWIN_TEXT, A_NORMAL);
mkattrn(SCROLLWIN_HEADING, A_BOLD);
mkattrn(SCROLLWIN_BOX, A_BOLD);
mkattrn(DIALOG_TEXT, A_NORMAL);
mkattrn(DIALOG_BOX, A_BOLD);
mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
mkattrn(DIALOG_MENU_BACK, A_NORMAL);
mkattrn(INPUT_BOX, A_BOLD);
mkattrn(INPUT_HEADING, A_BOLD);
mkattrn(INPUT_TEXT, A_NORMAL);
mkattrn(INPUT_FIELD, A_UNDERLINE);
mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
mkattrn(FUNCTION_TEXT, A_REVERSE);
}
static const struct nconf_attr_param no_color_theme_params[] = {
NO_COLOR_ATTR(attr_normal, A_NORMAL),
NO_COLOR_ATTR(attr_main_heading, A_BOLD | A_UNDERLINE),
NO_COLOR_ATTR(attr_main_menu_box, A_NORMAL),
NO_COLOR_ATTR(attr_main_menu_fore, A_STANDOUT),
NO_COLOR_ATTR(attr_main_menu_back, A_NORMAL),
NO_COLOR_ATTR(attr_main_menu_grey, A_NORMAL),
NO_COLOR_ATTR(attr_main_menu_heading, A_BOLD),
NO_COLOR_ATTR(attr_scrollwin_text, A_NORMAL),
NO_COLOR_ATTR(attr_scrollwin_heading, A_BOLD),
NO_COLOR_ATTR(attr_scrollwin_box, A_BOLD),
NO_COLOR_ATTR(attr_dialog_text, A_NORMAL),
NO_COLOR_ATTR(attr_dialog_menu_fore, A_STANDOUT),
NO_COLOR_ATTR(attr_dialog_menu_back, A_NORMAL),
NO_COLOR_ATTR(attr_dialog_box, A_BOLD),
NO_COLOR_ATTR(attr_input_box, A_BOLD),
NO_COLOR_ATTR(attr_input_heading, A_BOLD),
NO_COLOR_ATTR(attr_input_text, A_NORMAL),
NO_COLOR_ATTR(attr_input_field, A_UNDERLINE),
NO_COLOR_ATTR(attr_function_text, A_REVERSE),
NO_COLOR_ATTR(attr_function_highlight, A_BOLD),
{ /* sentinel */ }
};
void set_colors(void)
{
start_color();
use_default_colors();
set_normal_colors();
const struct nconf_attr_param *p;
int pair = 0;
if (has_colors()) {
normal_color_theme();
start_color();
use_default_colors();
p = color_theme_params;
} else {
/* give defaults */
no_colors_theme();
p = no_color_theme_params;
}
for (; p->attr; p++) {
int attr = p->highlight;
if (p->has_color) {
pair++;
init_pair(pair, p->color_fg, p->color_bg);
attr |= COLOR_PAIR(pair);
}
*p->attr = attr;
}
}
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win,
int starty,
int startx,
int width,
const char *string,
chtype color)
{ int length, x, y;
float temp;
if (win == NULL)
win = stdscr;
getyx(win, y, x);
if (startx != 0)
x = startx;
if (starty != 0)
y = starty;
if (width == 0)
width = 80;
length = strlen(string);
temp = (width - length) / 2;
x = startx + (int)temp;
(void) wattrset(win, color);
mvwprintw(win, y, x, "%s", string);
refresh();
void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs)
{
wattrset(win, attrs);
mvwprintw(win, y, (width - strlen(str)) / 2, "%s", str);
}
int get_line_no(const char *text)
@ -294,14 +245,14 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
msg_win = derwin(win, win_rows-2, msg_width, 1,
1+(total_width+2-msg_width)/2);
set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
set_menu_fore(menu, attr_dialog_menu_fore);
set_menu_back(menu, attr_dialog_menu_back);
(void) wattrset(win, attributes[DIALOG_BOX]);
wattrset(win, attr_dialog_box);
box(win, 0, 0);
/* print message */
(void) wattrset(msg_win, attributes[DIALOG_TEXT]);
wattrset(msg_win, attr_dialog_text);
fill_window(msg_win, msg);
set_menu_win(menu, win);
@ -405,16 +356,16 @@ int dialog_inputbox(WINDOW *main_window,
form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
keypad(form_win, TRUE);
(void) wattrset(form_win, attributes[INPUT_FIELD]);
wattrset(form_win, attr_input_field);
(void) wattrset(win, attributes[INPUT_BOX]);
wattrset(win, attr_input_box);
box(win, 0, 0);
(void) wattrset(win, attributes[INPUT_HEADING]);
wattrset(win, attr_input_heading);
if (title)
mvwprintw(win, 0, 3, "%s", title);
/* print message */
(void) wattrset(prompt_win, attributes[INPUT_TEXT]);
wattrset(prompt_win, attr_input_text);
fill_window(prompt_win, prompt);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
@ -576,7 +527,7 @@ void show_scroll_win(WINDOW *main_window,
/* create the pad */
pad = newpad(total_lines+10, total_cols+10);
(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
wattrset(pad, attr_scrollwin_text);
fill_window(pad, text);
win_lines = min(total_lines+4, lines-2);
@ -591,9 +542,9 @@ void show_scroll_win(WINDOW *main_window,
win = newwin(win_lines, win_cols, y, x);
keypad(win, TRUE);
/* show the help in the help window, and show the help panel */
(void) wattrset(win, attributes[SCROLLWIN_BOX]);
wattrset(win, attr_scrollwin_box);
box(win, 0, 0);
(void) wattrset(win, attributes[SCROLLWIN_HEADING]);
wattrset(win, attr_scrollwin_heading);
mvwprintw(win, 0, 3, " %s ", title);
panel = new_panel(win);
@ -604,10 +555,9 @@ void show_scroll_win(WINDOW *main_window,
text_cols, 0);
print_in_middle(win,
text_lines+2,
0,
text_cols,
"<OK>",
attributes[DIALOG_MENU_FORE]);
attr_dialog_menu_fore);
wrefresh(win);
res = wgetch(win);

View File

@ -32,30 +32,26 @@
typeof(b) _b = b;\
_a < _b ? _a : _b; })
typedef enum {
NORMAL = 1,
MAIN_HEADING,
MAIN_MENU_BOX,
MAIN_MENU_FORE,
MAIN_MENU_BACK,
MAIN_MENU_GREY,
MAIN_MENU_HEADING,
SCROLLWIN_TEXT,
SCROLLWIN_HEADING,
SCROLLWIN_BOX,
DIALOG_TEXT,
DIALOG_MENU_FORE,
DIALOG_MENU_BACK,
DIALOG_BOX,
INPUT_BOX,
INPUT_HEADING,
INPUT_TEXT,
INPUT_FIELD,
FUNCTION_TEXT,
FUNCTION_HIGHLIGHT,
ATTR_MAX
} attributes_t;
extern attributes_t attributes[];
extern int attr_normal;
extern int attr_main_heading;
extern int attr_main_menu_box;
extern int attr_main_menu_fore;
extern int attr_main_menu_back;
extern int attr_main_menu_grey;
extern int attr_main_menu_heading;
extern int attr_scrollwin_text;
extern int attr_scrollwin_heading;
extern int attr_scrollwin_box;
extern int attr_dialog_text;
extern int attr_dialog_menu_fore;
extern int attr_dialog_menu_back;
extern int attr_dialog_box;
extern int attr_input_box;
extern int attr_input_heading;
extern int attr_input_text;
extern int attr_input_field;
extern int attr_function_text;
extern int attr_function_highlight;
typedef enum {
F_HELP = 1,
@ -72,12 +68,7 @@ typedef enum {
void set_colors(void);
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win,
int starty,
int startx,
int width,
const char *string,
chtype color);
void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs);
int get_line_length(const char *line);
int get_line_no(const char *text);
const char *get_line(const char *text, int line_no);

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,9 @@
/* A Bison parser, made by GNU Bison 3.1. */
/* A Bison parser, made by GNU Bison 3.7.6. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -15,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -30,6 +31,10 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_PARSER_TAB_H_INCLUDED
# define YY_YY_PARSER_TAB_H_INCLUDED
/* Debug traces. */
@ -40,72 +45,72 @@
extern int yydebug;
#endif
/* Token type. */
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
T_HELPTEXT = 258,
T_WORD = 259,
T_WORD_QUOTE = 260,
T_ALLNOCONFIG_Y = 261,
T_BOOL = 262,
T_CHOICE = 263,
T_CLOSE_PAREN = 264,
T_COLON_EQUAL = 265,
T_COMMENT = 266,
T_CONFIG = 267,
T_DEFAULT = 268,
T_DEFCONFIG_LIST = 269,
T_DEF_BOOL = 270,
T_DEF_TRISTATE = 271,
T_DEPENDS = 272,
T_ENDCHOICE = 273,
T_ENDIF = 274,
T_ENDMENU = 275,
T_HELP = 276,
T_HEX = 277,
T_IF = 278,
T_IMPLY = 279,
T_INT = 280,
T_MAINMENU = 281,
T_MENU = 282,
T_MENUCONFIG = 283,
T_MODULES = 284,
T_ON = 285,
T_OPEN_PAREN = 286,
T_OPTION = 287,
T_OPTIONAL = 288,
T_PLUS_EQUAL = 289,
T_PROMPT = 290,
T_RANGE = 291,
T_RESET = 292,
T_SELECT = 293,
T_SOURCE = 294,
T_STRING = 295,
T_TRISTATE = 296,
T_VISIBLE = 297,
T_EOL = 298,
T_ASSIGN_VAL = 299,
T_OR = 300,
T_AND = 301,
T_EQUAL = 302,
T_UNEQUAL = 303,
T_LESS = 304,
T_LESS_EQUAL = 305,
T_GREATER = 306,
T_GREATER_EQUAL = 307,
T_NOT = 308
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
T_HELPTEXT = 258, /* T_HELPTEXT */
T_WORD = 259, /* T_WORD */
T_WORD_QUOTE = 260, /* T_WORD_QUOTE */
T_BOOL = 261, /* T_BOOL */
T_CHOICE = 262, /* T_CHOICE */
T_CLOSE_PAREN = 263, /* T_CLOSE_PAREN */
T_COLON_EQUAL = 264, /* T_COLON_EQUAL */
T_COMMENT = 265, /* T_COMMENT */
T_CONFIG = 266, /* T_CONFIG */
T_DEFAULT = 267, /* T_DEFAULT */
T_DEF_BOOL = 268, /* T_DEF_BOOL */
T_DEF_TRISTATE = 269, /* T_DEF_TRISTATE */
T_DEPENDS = 270, /* T_DEPENDS */
T_ENDCHOICE = 271, /* T_ENDCHOICE */
T_ENDIF = 272, /* T_ENDIF */
T_ENDMENU = 273, /* T_ENDMENU */
T_HELP = 274, /* T_HELP */
T_HEX = 275, /* T_HEX */
T_IF = 276, /* T_IF */
T_IMPLY = 277, /* T_IMPLY */
T_INT = 278, /* T_INT */
T_MAINMENU = 279, /* T_MAINMENU */
T_MENU = 280, /* T_MENU */
T_MENUCONFIG = 281, /* T_MENUCONFIG */
T_MODULES = 282, /* T_MODULES */
T_ON = 283, /* T_ON */
T_OPEN_PAREN = 284, /* T_OPEN_PAREN */
T_OPTIONAL = 285, /* T_OPTIONAL */
T_PLUS_EQUAL = 286, /* T_PLUS_EQUAL */
T_PROMPT = 287, /* T_PROMPT */
T_RANGE = 288, /* T_RANGE */
T_RESET = 289, /* T_RESET */
T_SELECT = 290, /* T_SELECT */
T_SOURCE = 291, /* T_SOURCE */
T_STRING = 292, /* T_STRING */
T_TRISTATE = 293, /* T_TRISTATE */
T_VISIBLE = 294, /* T_VISIBLE */
T_EOL = 295, /* T_EOL */
T_ASSIGN_VAL = 296, /* T_ASSIGN_VAL */
T_OR = 297, /* T_OR */
T_AND = 298, /* T_AND */
T_EQUAL = 299, /* T_EQUAL */
T_UNEQUAL = 300, /* T_UNEQUAL */
T_LESS = 301, /* T_LESS */
T_LESS_EQUAL = 302, /* T_LESS_EQUAL */
T_GREATER = 303, /* T_GREATER */
T_GREATER_EQUAL = 304, /* T_GREATER_EQUAL */
T_NOT = 305 /* T_NOT */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
char *string;
struct symbol *symbol;
struct expr *expr;
@ -115,7 +120,6 @@ union YYSTYPE
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1

View File

@ -12,6 +12,7 @@
#include <stdbool.h>
#include "lkc.h"
#include "internal.h"
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
@ -28,7 +29,7 @@ static bool zconf_endtoken(const char *tokenname,
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry;
struct menu *current_menu, *current_entry;
%}
@ -45,7 +46,6 @@ static struct menu *current_menu, *current_entry;
%token <string> T_HELPTEXT
%token <string> T_WORD
%token <string> T_WORD_QUOTE
%token T_ALLNOCONFIG_Y
%token T_BOOL
%token T_CHOICE
%token T_CLOSE_PAREN
@ -53,7 +53,6 @@ static struct menu *current_menu, *current_entry;
%token T_COMMENT
%token T_CONFIG
%token T_DEFAULT
%token T_DEFCONFIG_LIST
%token T_DEF_BOOL
%token T_DEF_TRISTATE
%token T_DEPENDS
@ -71,7 +70,6 @@ static struct menu *current_menu, *current_entry;
%token T_MODULES
%token T_ON
%token T_OPEN_PAREN
%token T_OPTION
%token T_OPTIONAL
%token T_PLUS_EQUAL
%token T_PROMPT
@ -120,20 +118,24 @@ mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL
stmt_list:
/* empty */
| stmt_list common_stmt
| stmt_list assignment_stmt
| stmt_list choice_stmt
| stmt_list comment_stmt
| stmt_list config_stmt
| stmt_list if_stmt
| stmt_list menu_stmt
| stmt_list menuconfig_stmt
| stmt_list source_stmt
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
| stmt_list error T_EOL { zconf_error("invalid statement"); }
;
common_stmt:
if_stmt
| comment_stmt
| config_stmt
| menuconfig_stmt
| source_stmt
| assignment_stmt
stmt_list_in_choice:
/* empty */
| stmt_list_in_choice comment_stmt
| stmt_list_in_choice config_stmt
| stmt_list_in_choice if_stmt_in_choice
| stmt_list_in_choice error T_EOL { zconf_error("invalid statement"); }
;
/* config/menuconfig entry */
@ -215,19 +217,12 @@ config_option: T_RANGE symbol symbol if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
};
config_option: T_OPTION T_MODULES T_EOL
config_option: T_MODULES T_EOL
{
menu_add_option_modules();
};
config_option: T_OPTION T_DEFCONFIG_LIST T_EOL
{
menu_add_option_defconfig_list();
};
config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL
{
menu_add_option_allnoconfig_y();
if (modules_sym)
zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'",
current_entry->sym->name, modules_sym->name);
modules_sym = current_entry->sym;
};
/* choice entry */
@ -255,7 +250,7 @@ choice_end: end
}
};
choice_stmt: choice_entry choice_block choice_end
choice_stmt: choice_entry stmt_list_in_choice choice_end
;
choice_option_list:
@ -311,11 +306,6 @@ default:
| T_DEF_BOOL { $$ = S_BOOLEAN; }
| T_DEF_TRISTATE { $$ = S_TRISTATE; }
choice_block:
/* empty */
| choice_block common_stmt
;
/* if entry */
if_entry: T_IF expr T_EOL
@ -337,6 +327,9 @@ if_end: end
if_stmt: if_entry stmt_list if_end
;
if_stmt_in_choice: if_entry stmt_list_in_choice if_end
;
/* menu entry */
menu: T_MENU T_WORD_QUOTE T_EOL
@ -517,7 +510,7 @@ void conf_parse(const char *name)
}
if (yynerrs)
exit(1);
sym_set_change_count(1);
conf_set_changed(true);
}
static bool zconf_endtoken(const char *tokenname,
@ -723,5 +716,3 @@ void zconfdump(FILE *out)
}
}
}
#include "menu.c"

View File

@ -114,7 +114,7 @@ static char *do_error_if(int argc, char *argv[])
if (!strcmp(argv[0], "y"))
pperror("%s", argv[1]);
return NULL;
return xstrdup("");
}
static char *do_filename(int argc, char *argv[])

View File

@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-2.0-only
PKG="Qt5Core Qt5Gui Qt5Widgets"
PKG2="QtCore QtGui"
if [ -z "$(command -v pkg-config)" ]; then
echo >&2 "*"
@ -12,21 +11,14 @@ if [ -z "$(command -v pkg-config)" ]; then
fi
if pkg-config --exists $PKG; then
echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\"
echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\"
echo libs=\"$(pkg-config --libs $PKG)\"
echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\"
exit 0
fi
if pkg-config --exists $PKG2; then
echo cflags=\"$(pkg-config --cflags $PKG2)\"
echo libs=\"$(pkg-config --libs $PKG2)\"
echo moc=\"$(pkg-config --variable=moc_location QtCore)\"
exit 0
fi
echo >&2 "*"
echo >&2 "* Could not find Qt via pkg-config."
echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"
echo >&2 "* Could not find Qt5 via pkg-config."
echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
echo >&2 "*"
exit 1

File diff suppressed because it is too large Load Diff

View File

@ -3,23 +3,22 @@
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
*/
#include <QTextBrowser>
#include <QTreeWidget>
#include <QMainWindow>
#include <QHeaderView>
#include <qsettings.h>
#include <QPushButton>
#include <QSettings>
#include <QLineEdit>
#include <QSplitter>
#include <QCheckBox>
#include <QDialog>
#include <QHeaderView>
#include <QLineEdit>
#include <QMainWindow>
#include <QPushButton>
#include <QSettings>
#include <QSplitter>
#include <QStyledItemDelegate>
#include <QTextBrowser>
#include <QTreeWidget>
#include "expr.h"
class ConfigView;
class ConfigList;
class ConfigItem;
class ConfigLineEdit;
class ConfigMainWindow;
class ConfigSettings : public QSettings {
@ -30,7 +29,7 @@ public:
};
enum colIdx {
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
promptColIdx, nameColIdx, dataColIdx
};
enum listMode {
singleMode, menuMode, symbolMode, fullMode, listMode
@ -43,13 +42,16 @@ class ConfigList : public QTreeWidget {
Q_OBJECT
typedef class QTreeWidget Parent;
public:
ConfigList(ConfigView* p, const char *name = 0);
ConfigList(QWidget *parent, const char *name = 0);
~ConfigList();
void reinit(void);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
ConfigItem* findConfigItem(struct menu *);
void setSelected(QTreeWidgetItem *item, bool enable) {
for (int i = 0; i < selectedItems().size(); i++)
selectedItems().at(i)->setSelected(false);
item->setSelected(enable);
}
protected:
void keyPressEvent(QKeyEvent *e);
@ -63,61 +65,52 @@ protected:
public slots:
void setRootMenu(struct menu *menu);
void updateList(ConfigItem *item);
void updateList();
void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item);
void updateSelection(void);
void saveSettings(void);
void setOptionMode(QAction *action);
void setShowName(bool on);
signals:
void menuChanged(struct menu *menu);
void menuSelected(struct menu *menu);
void itemSelected(struct menu *menu);
void parentSelected(void);
void gotFocus(struct menu *);
void showNameChanged(bool on);
public:
void updateListAll(void)
{
updateAll = true;
updateList(NULL);
updateList();
updateAll = false;
}
ConfigList* listView()
{
return this;
}
ConfigItem* firstChild() const
{
return (ConfigItem *)children().first();
}
void addColumn(colIdx idx)
{
showColumn(idx);
}
void removeColumn(colIdx idx)
{
hideColumn(idx);
}
void setAllOpen(bool open);
void setParentMenu(void);
bool menuSkip(struct menu *);
void updateMenuList(ConfigItem *parent, struct menu*);
void updateMenuList(ConfigList *parent, struct menu*);
void updateMenuList(struct menu *menu);
bool updateAll;
QPixmap symbolYesPix, symbolModPix, symbolNoPix;
QPixmap choiceYesPix, choiceNoPix;
QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
bool showName, showRange, showData;
bool showName;
enum listMode mode;
enum optionMode optMode;
struct menu *rootEntry;
QPalette disabledColorGroup;
QPalette inactivedColorGroup;
QMenu* headerPopup;
static QList<ConfigList *> allLists;
static void updateListForAll();
static void updateListAllForAll();
static QAction *showNormalAction, *showAllAction, *showPromptAction;
};
class ConfigItem : public QTreeWidgetItem {
@ -140,7 +133,6 @@ public:
}
~ConfigItem(void);
void init(void);
void okRename(int col);
void updateMenu(void);
void testUpdateMenu(bool v);
ConfigList* listView() const
@ -165,82 +157,36 @@ public:
return ret;
}
void setText(colIdx idx, const QString& text)
{
Parent::setText(idx, text);
}
QString text(colIdx idx) const
{
return Parent::text(idx);
}
void setPixmap(colIdx idx, const QIcon &icon)
{
Parent::setIcon(idx, icon);
}
const QIcon pixmap(colIdx idx) const
{
return icon(idx);
}
// TODO: Implement paintCell
ConfigItem* nextItem;
struct menu *menu;
bool visible;
bool goParent;
static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon;
static QIcon choiceYesIcon, choiceNoIcon;
static QIcon menuIcon, menubackIcon;
};
class ConfigLineEdit : public QLineEdit {
Q_OBJECT
typedef class QLineEdit Parent;
class ConfigItemDelegate : public QStyledItemDelegate
{
private:
struct menu *menu;
public:
ConfigLineEdit(ConfigView* parent);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
void show(ConfigItem *i);
void keyPressEvent(QKeyEvent *e);
public:
ConfigItem *item;
};
class ConfigView : public QWidget {
Q_OBJECT
typedef class QWidget Parent;
public:
ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void);
static void updateList(ConfigItem* item);
static void updateListAll(void);
bool showName(void) const { return list->showName; }
bool showRange(void) const { return list->showRange; }
bool showData(void) const { return list->showData; }
public slots:
void setShowName(bool);
void setShowRange(bool);
void setShowData(bool);
void setOptionMode(QAction *);
signals:
void showNameChanged(bool);
void showRangeChanged(bool);
void showDataChanged(bool);
public:
ConfigList* list;
ConfigLineEdit* lineEdit;
static ConfigView* viewList;
ConfigView* nextView;
static QAction *showNormalAction;
static QAction *showAllAction;
static QAction *showPromptAction;
ConfigItemDelegate(QObject *parent = nullptr)
: QStyledItemDelegate(parent) {}
QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
};
class ConfigInfoView : public QTextBrowser {
Q_OBJECT
typedef class QTextBrowser Parent;
QMenu *contextMenu;
public:
ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; }
@ -249,6 +195,7 @@ public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
void setShowDebug(bool);
void clicked (const QUrl &url);
signals:
void showDebugChanged(bool);
@ -260,8 +207,7 @@ protected:
QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str);
QMenu *createStandardContextMenu(const QPoint & pos);
void contextMenuEvent(QContextMenuEvent *e);
void contextMenuEvent(QContextMenuEvent *event);
struct symbol *sym;
struct menu *_menu;
@ -272,7 +218,7 @@ class ConfigSearchWindow : public QDialog {
Q_OBJECT
typedef class QDialog Parent;
public:
ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0);
ConfigSearchWindow(ConfigMainWindow *parent);
public slots:
void saveSettings(void);
@ -282,7 +228,7 @@ protected:
QLineEdit* editField;
QPushButton* searchButton;
QSplitter* split;
ConfigView* list;
ConfigList *list;
ConfigInfoView* info;
struct symbol **result;
@ -298,6 +244,7 @@ public:
ConfigMainWindow(void);
public slots:
void changeMenu(struct menu *);
void changeItens(struct menu *);
void setMenuLink(struct menu *);
void listFocusChanged(void);
void goBack(void);
@ -316,12 +263,9 @@ protected:
void closeEvent(QCloseEvent *e);
ConfigSearchWindow *searchWindow;
ConfigView *menuView;
ConfigList *menuList;
ConfigView *configView;
ConfigList *configList;
ConfigInfoView *helpText;
QToolBar *toolBar;
QAction *backAction;
QAction *singleViewAction;
QAction *splitViewAction;

View File

@ -3,11 +3,11 @@
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <sys/utsname.h>
#include "lkc.h"
@ -15,23 +15,28 @@ struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_mod = {
};
struct symbol symbol_mod = {
.name = "m",
.curr = { "m", mod },
.flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_no = {
};
struct symbol symbol_no = {
.name = "n",
.curr = { "n", no },
.flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_empty = {
};
static struct symbol symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
};
struct symbol *sym_defconfig_list;
struct symbol *modules_sym;
tristate modules_val;
static tristate modules_val;
int recursive_is_error;
enum symbol_type sym_get_type(struct symbol *sym)
@ -222,7 +227,7 @@ static void sym_calc_visibility(struct symbol *sym)
sym_set_changed(sym);
}
tri = no;
if (sym->implied.expr && sym->dir_dep.tri != no)
if (sym->implied.expr)
tri = expr_calc_value(sym->implied.expr);
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes;
@ -373,6 +378,8 @@ void sym_calc_value(struct symbol *sym)
if (sym->implied.tri != no) {
sym->flags |= SYMBOL_WRITE;
newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
newval.tri = EXPR_AND(newval.tri,
sym->dir_dep.tri);
}
}
calc_newval:
@ -381,8 +388,7 @@ void sym_calc_value(struct symbol *sym)
else
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod &&
(sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
break;
case S_STRING:
@ -446,7 +452,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
sym_add_change_count(1);
conf_set_changed(true);
sym_calc_value(modules_sym);
}
@ -464,8 +470,6 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
return false;
if (sym->visible <= sym->rev_dep.tri)
return false;
if (sym->implied.tri == yes && val == mod)
return false;
if (sym_is_choice_value(sym) && sym->visible == yes)
return val == yes;
return val >= sym->rev_dep.tri && val <= sym->visible;
@ -812,7 +816,7 @@ struct symbol *sym_lookup(const char *name, int flags)
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
symbol->flags |= flags;
symbol->flags = flags;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;

View File

@ -13,230 +13,316 @@ import sys
import os
import re
import getopt
import shutil
# Commandline options
opt_dryrun = False
def parseVer_1234(match, filepath):
progname = match.group(1)
progversion = (int(match.group(2)) << 64) |\
(int(match.group(3)) << 48) |\
(int(match.group(4)) << 32) |\
(int(match.group(5)) << 16)
return (progname, progversion)
progname = match.group(1)
progversion = (
(int(match.group(2)) << 64)
| (int(match.group(3)) << 48)
| (int(match.group(4)) << 32)
| (int(match.group(5)) << 16)
)
return (progname, progversion)
def parseVer_123(match, filepath):
progname = match.group(1)
try:
patchlevel = match.group(5)
except IndexError as e:
patchlevel = None
if patchlevel:
patchlevel = ord(patchlevel[0])
else:
patchlevel = 0
progversion = (int(match.group(2)) << 64) |\
(int(match.group(3)) << 48) |\
(int(match.group(4)) << 32) |\
patchlevel
return (progname, progversion)
progname = match.group(1)
try:
patchlevel = match.group(5)
except IndexError as e:
patchlevel = None
if patchlevel:
patchlevel = ord(patchlevel[0])
else:
patchlevel = 0
progversion = (
(int(match.group(2)) << 64)
| (int(match.group(3)) << 48)
| (int(match.group(4)) << 32)
| patchlevel
)
return (progname, progversion)
def parseVer_12(match, filepath):
progname = match.group(1)
try:
patchlevel = match.group(4)
except IndexError as e:
patchlevel = None
if patchlevel:
patchlevel = ord(patchlevel[0])
else:
patchlevel = 0
progversion = (int(match.group(2)) << 64) |\
(int(match.group(3)) << 48) |\
patchlevel
return (progname, progversion)
progname = match.group(1)
try:
patchlevel = match.group(4)
except IndexError as e:
patchlevel = None
if patchlevel:
patchlevel = ord(patchlevel[0])
else:
patchlevel = 0
progversion = (int(match.group(2)) << 64) | (int(match.group(3)) << 48) | patchlevel
return (progname, progversion)
def parseVer_r(match, filepath):
progname = match.group(1)
progversion = (int(match.group(2)) << 64)
return (progname, progversion)
progname = match.group(1)
progversion = int(match.group(2)) << 64
return (progname, progversion)
def parseVer_ymd_GIT_SHASUM(match, filepath):
progname = match.group(1)
progversion = (
(int(match.group(2)) << 64)
| (int(match.group(3)) << 48)
| (int(match.group(4)) << 32)
)
return (progname, progversion)
def parseVer_ymd(match, filepath):
progname = match.group(1)
progversion = (int(match.group(2)) << 64) |\
(int(match.group(3)) << 48) |\
(int(match.group(4)) << 32)
return (progname, progversion)
progname = match.group(1)
progversion = (
(int(match.group(2)) << 64)
| (int(match.group(3)) << 48)
| (int(match.group(4)) << 32)
)
return (progname, progversion)
def parseVer_GIT(match, filepath):
progname = match.group(1)
st = os.stat(filepath)
progversion = int(st.st_mtime) << 64
return (progname, progversion)
progname = match.group(1)
st = os.stat(filepath)
progversion = int(st.st_mtime) << 64
return (progname, progversion)
extensions = (
".tar.gz",
".tar.bz2",
".tar.xz",
".orig.tar.gz",
".orig.tar.bz2",
".orig.tar.xz",
".zip",
".tgz",
".tbz",
".txz",
".tar.gz",
".tar.bz2",
".tar.xz",
".orig.tar.gz",
".orig.tar.bz2",
".orig.tar.xz",
".zip",
".tgz",
".tbz",
".txz",
)
versionRegex = (
(re.compile(r"(.+)[-_](\d+)\.(\d+)\.(\d+)\.(\d+)"), parseVer_1234), # xxx-1.2.3.4
(re.compile(r"(.+)[-_](\d\d\d\d)-?(\d\d)-?(\d\d)"), parseVer_ymd), # xxx-YYYY-MM-DD
(re.compile(r"(.+)[-_]([0-9a-fA-F]{40,40})"), parseVer_GIT), # xxx-GIT_SHASUM
(re.compile(r"(.+)[-_](\d+)\.(\d+)\.(\d+)(\w?)"), parseVer_123), # xxx-1.2.3a
(re.compile(r"(.+)[-_](\d+)_(\d+)_(\d+)"), parseVer_123), # xxx-1_2_3
(re.compile(r"(.+)[-_](\d+)\.(\d+)(\w?)"), parseVer_12), # xxx-1.2a
(re.compile(r"(.+)[-_]r?(\d+)"), parseVer_r), # xxx-r1111
(re.compile(r"(gcc[-_]\d+)\.(\d+)\.(\d+)"), parseVer_12), # gcc.1.2
(re.compile(r"(linux[-_]\d+\.\d+)\.(\d+)"), parseVer_r), # linux.1
(re.compile(r"(.+)[-_](\d+)\.(\d+)\.(\d+)\.(\d+)"), parseVer_1234), # xxx-1.2.3.4
(
re.compile(r"(.+)[-_](\d\d\d\d)-?(\d\d)-?(\d\d)-"),
parseVer_ymd_GIT_SHASUM,
), # xxx-YYYY-MM-DD-GIT_SHASUM
(re.compile(r"(.+)[-_](\d\d\d\d)-?(\d\d)-?(\d\d)"), parseVer_ymd), # xxx-YYYY-MM-DD
(re.compile(r"(.+)[-_]([0-9a-fA-F]{40,40})"), parseVer_GIT), # xxx-GIT_SHASUM
(re.compile(r"(.+)[-_](\d+)\.(\d+)\.(\d+)(\w?)"), parseVer_123), # xxx-1.2.3a
(re.compile(r"(.+)[-_]v(\d+)\.(\d+)\.(\d+)(\w?)"), parseVer_123), # xxx-v1.2.3a
(re.compile(r"(.+)[-_](\d+)_(\d+)_(\d+)"), parseVer_123), # xxx-1_2_3
(re.compile(r"(.+)[-_](\d+)\.(\d+)(\w?)"), parseVer_12), # xxx-1.2a
(re.compile(r"(.+)[-_]v(\d+)\.(\d+)(\w?)"), parseVer_12), # xxx-v1.2a
(re.compile(r"(.+)[-_]r?(\d+)"), parseVer_r), # xxx-r1111
)
blacklist = [
("linux", re.compile(r"linux-\d.*")),
("gcc", re.compile(r"gcc-.*")),
("wl_apsta", re.compile(r"wl_apsta.*")),
(".fw", re.compile(r".*\.fw")),
(".arm", re.compile(r".*\.arm")),
(".bin", re.compile(r".*\.bin")),
("rt-firmware", re.compile(r"RT[\d\w]+_Firmware.*")),
("wl_apsta", re.compile(r"wl_apsta.*")),
(".fw", re.compile(r".*\.fw")),
(".arm", re.compile(r".*\.arm")),
(".bin", re.compile(r".*\.bin")),
("rt-firmware", re.compile(r"RT[\d\w]+_Firmware.*")),
]
class EntryParseError(Exception): pass
class EntryParseError(Exception):
pass
class Entry:
def __init__(self, directory, filename):
self.directory = directory
self.filename = filename
self.progname = ""
self.fileext = ""
def __init__(self, directory, builddir, filename):
self.directory = directory
self.filename = filename
self.builddir = builddir
self.progname = ""
self.fileext = ""
self.filenoext = ""
for ext in extensions:
if filename.endswith(ext):
filename = filename[0:0-len(ext)]
self.fileext = ext
break
else:
print(self.filename, "has an unknown file-extension")
raise EntryParseError("ext")
for (regex, parseVersion) in versionRegex:
match = regex.match(filename)
if match:
(self.progname, self.version) = parseVersion(
match, directory + "/" + filename + self.fileext)
break
else:
print(self.filename, "has an unknown version pattern")
raise EntryParseError("ver")
if os.path.isdir(self.getPath()):
self.filenoext = filename
else:
for ext in extensions:
if filename.endswith(ext):
filename = filename[0 : 0 - len(ext)]
self.filenoext = filename
self.fileext = ext
break
else:
print(self.filename, "has an unknown file-extension")
raise EntryParseError("ext")
for (regex, parseVersion) in versionRegex:
match = regex.match(filename)
if match:
(self.progname, self.version) = parseVersion(
match, directory + "/" + filename + self.fileext
)
break
else:
print(self.filename, "has an unknown version pattern")
raise EntryParseError("ver")
def getPath(self):
return (self.directory + "/" + self.filename).replace("//", "/")
def getPath(self):
return (self.directory + "/" + self.filename).replace("//", "/")
def deleteFile(self):
path = self.getPath()
print("Deleting", path)
if not opt_dryrun:
os.unlink(path)
def getBuildPaths(self):
paths = []
for subdir in os.scandir(self.builddir):
package_build_dir = os.path.join(subdir.path, self.filenoext)
if os.path.exists(package_build_dir):
paths.append(package_build_dir)
return paths
def deleteFile(self):
path = self.getPath()
print("Deleting", path)
if not opt_dryrun:
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.unlink(path)
def deleteBuildDir(self):
paths = self.getBuildPaths()
for path in paths:
print("Deleting BuildDir", path)
if not opt_dryrun:
shutil.rmtree(path)
def __ge__(self, y):
return self.version >= y.version
def __ge__(self, y):
return self.version >= y.version
def usage():
print("OpenWrt download directory cleanup utility")
print("Usage: " + sys.argv[0] + " [OPTIONS] <path/to/dl>")
print("")
print(" -d|--dry-run Do a dry-run. Don't delete any files")
print(" -B|--show-blacklist Show the blacklist and exit")
print(" -w|--whitelist ITEM Remove ITEM from blacklist")
print("OpenWrt download directory cleanup utility")
print("Usage: " + sys.argv[0] + " [OPTIONS] <path/to/dl>")
print("")
print(" -d|--dry-run Do a dry-run. Don't delete any files")
print(" -B|--show-blacklist Show the blacklist and exit")
print(" -w|--whitelist ITEM Remove ITEM from blacklist")
print(
" -D|--download-dir Provide path to dl dir to clean also the build directory"
)
print(
" -b|--build-dir Provide path to build dir to clean also the build directory"
)
def main(argv):
global opt_dryrun
global opt_dryrun
try:
(opts, args) = getopt.getopt(argv[1:],
"hdBw:",
[ "help", "dry-run", "show-blacklist", "whitelist=", ])
if len(args) != 1:
usage()
return 1
except getopt.GetoptError as e:
usage()
return 1
directory = args[0]
try:
(opts, args) = getopt.getopt(
argv[1:],
"hdBwDb:",
[
"help",
"dry-run",
"show-blacklist",
"whitelist=",
"download-dir=",
"build-dir=",
],
)
except getopt.GetoptError as e:
usage()
return 1
if not os.path.exists(directory):
print("Can't find dl path", directory)
return 1
directory = "dl/"
builddir = "build_dir/"
for (o, v) in opts:
if o in ("-h", "--help"):
usage()
return 0
if o in ("-d", "--dry-run"):
opt_dryrun = True
if o in ("-w", "--whitelist"):
for i in range(0, len(blacklist)):
(name, regex) = blacklist[i]
if name == v:
del blacklist[i]
break
else:
print("Whitelist error: Item", v,\
"is not in blacklist")
return 1
if o in ("-B", "--show-blacklist"):
for (name, regex) in blacklist:
sep = "\t\t"
if len(name) >= 8:
sep = "\t"
print("%s%s(%s)" % (name, sep, regex.pattern))
return 0
for (o, v) in opts:
if o in ("-h", "--help"):
usage()
return 0
if o in ("-d", "--dry-run"):
opt_dryrun = True
if o in ("-w", "--whitelist"):
for i in range(0, len(blacklist)):
(name, regex) = blacklist[i]
if name == v:
del blacklist[i]
break
else:
print("Whitelist error: Item", v, "is not in blacklist")
return 1
if o in ("-B", "--show-blacklist"):
for (name, regex) in blacklist:
sep = "\t\t"
if len(name) >= 8:
sep = "\t"
print("%s%s(%s)" % (name, sep, regex.pattern))
return 0
if o in ("-D", "--download-dir"):
directory = v
if o in ("-b", "--build-dir"):
builddir = v
# Create a directory listing and parse the file names.
entries = []
for filename in os.listdir(directory):
if filename == "." or filename == "..":
continue
for (name, regex) in blacklist:
if regex.match(filename):
if opt_dryrun:
print(filename, "is blacklisted")
break
else:
try:
entries.append(Entry(directory, filename))
except EntryParseError as e:
pass
if not os.path.exists(directory):
print("Can't find dl path", directory)
return 1
# Create a map of programs
progmap = {}
for entry in entries:
if entry.progname in progmap.keys():
progmap[entry.progname].append(entry)
else:
progmap[entry.progname] = [entry,]
if not os.path.exists(builddir):
print("Can't find dl path", builddir)
return 1
# Traverse the program map and delete everything but the last version
for prog in progmap:
lastVersion = None
versions = progmap[prog]
for version in versions:
if lastVersion is None or version >= lastVersion:
lastVersion = version
if lastVersion:
for version in versions:
if version is not lastVersion:
version.deleteFile()
if opt_dryrun:
print("Keeping", lastVersion.getPath())
# Create a directory listing and parse the file names.
entries = []
for filename in os.listdir(directory):
if filename == "." or filename == "..":
continue
for (name, regex) in blacklist:
if regex.match(filename):
if opt_dryrun:
print(filename, "is blacklisted")
break
else:
try:
entries.append(Entry(directory, builddir, filename))
except EntryParseError as e:
pass
# Create a map of programs
progmap = {}
for entry in entries:
if entry.progname in progmap.keys():
progmap[entry.progname].append(entry)
else:
progmap[entry.progname] = [
entry,
]
# Traverse the program map and delete everything but the last version
for prog in progmap:
lastVersion = None
versions = progmap[prog]
for version in versions:
if lastVersion:
if os.path.isdir(lastVersion.getPath()) and not os.path.isdir(version.getPath()):
continue
if lastVersion is None or version >= lastVersion:
lastVersion = version
if lastVersion:
for version in versions:
if version is not lastVersion:
version.deleteFile()
if builddir:
version.deleteBuildDir()
if opt_dryrun:
print("Keeping", lastVersion.getPath())
return 0
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))
sys.exit(main(sys.argv))

View File

@ -207,7 +207,7 @@ class GitHubCommitTsCache(object):
class DownloadGitHubTarball(object):
"""Download and repack archive tarabll from GitHub.
"""Download and repack archive tarball from GitHub.
Compared with the method of packing after cloning the whole repo, this
method is more friendly to users with fragile internet connection.
@ -220,7 +220,7 @@ class DownloadGitHubTarball(object):
- GitHub archives do not contain source codes for submodules.
- GitHub archives seem to respect .gitattributes and ignore pathes with
- GitHub archives seem to respect .gitattributes and ignore paths with
export-ignore attributes.
For the first two issues, the method will fail loudly to allow fallback to

View File

@ -56,10 +56,8 @@ sub localmirrors {
sub which($) {
my $prog = shift;
my $res = `which $prog`;
my $res = `command -v $prog`;
$res or return undef;
$res =~ /^no / and return undef;
$res =~ /not found/ and return undef;
return $res;
}
@ -72,29 +70,30 @@ sub hash_cmd() {
return undef;
}
sub tool_present {
my $tool_name = shift;
my $compare_line = shift;
my $present = 0;
if (open TOOL, "$tool_name --version 2>/dev/null |") {
if (defined(my $line = readline TOOL)) {
$present = 1 if $line =~ /^$compare_line /;
}
close TOOL;
}
return $present
}
sub download_cmd {
my $url = shift;
my $have_curl = 0;
my $have_aria2c = 0;
my $filename = shift;
my $additional_mirrors = join(" ", map "$_/$filename", @_);
my @chArray = ('a'..'z', 'A'..'Z', 0..9);
my $rfn = join '', "${filename}_", map{ $chArray[int rand @chArray] } 0..9;
if (open CURL, '-|', 'curl', '--version') {
if (defined(my $line = readline CURL)) {
$have_curl = 1 if $line =~ /^curl /;
}
close CURL;
}
if (open ARIA2C, '-|', 'aria2c', '--version') {
if (defined(my $line = readline ARIA2C)) {
$have_aria2c = 1 if $line =~ /^aria2 /;
}
close ARIA2C;
}
if ($have_aria2c) {
if (tool_present('aria2c', 'aria2')) {
@mirrors=();
return join(" ", "[ -d $ENV{'TMPDIR'}/aria2c ] || mkdir $ENV{'TMPDIR'}/aria2c;",
"touch $ENV{'TMPDIR'}/aria2c/${rfn}_spp;",
@ -105,7 +104,7 @@ sub download_cmd {
"-d $ENV{'TMPDIR'}/aria2c -o $rfn;",
"cat $ENV{'TMPDIR'}/aria2c/$rfn;",
"rm $ENV{'TMPDIR'}/aria2c/$rfn $ENV{'TMPDIR'}/aria2c/${rfn}_spp");
} elsif ($have_curl) {
} elsif (tool_present('curl', 'curl')) {
return (qw(curl -f --connect-timeout 20 --retry 5 --location),
$check_certificate ? () : '--insecure',
shellwords($ENV{CURL_OPTIONS} || ''),
@ -224,19 +223,17 @@ foreach my $mirror (@ARGV) {
if ($mirror =~ /^\@SF\/(.+)$/) {
# give sourceforge a few more tries, because it redirects to different mirrors
for (1 .. 5) {
push @mirrors, "https://netix.dl.sourceforge.net/$1";
push @mirrors, "https://freefr.dl.sourceforge.net/$1";
push @mirrors, "https://downloads.sourceforge.net/$1";
}
} elsif ($mirror =~ /^\@OPENWRT$/) {
# use OpenWrt source server directly
} elsif ($mirror =~ /^\@DEBIAN\/(.+)$/) {
push @mirrors, "https://mirrors.tencent.com/debian/$1";
push @mirrors, "https://ftp.debian.org/debian/$1";
push @mirrors, "https://mirror.leaseweb.com/debian/$1";
push @mirrors, "https://mirror.netcologne.de/debian/$1";
push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/debian/$1";
push @mirrors, "https://mirrors.ustc.edu.cn/debian/$1"
} elsif ($mirror =~ /^\@APACHE\/(.+)$/) {
push @mirrors, "https://mirrors.cloud.tencent.com/apache/$1";
push @mirrors, "https://mirror.netcologne.de/apache.org/$1";
push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1";
push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1";
@ -246,17 +243,14 @@ foreach my $mirror (@ARGV) {
push @mirrors, "http://ftp.jaist.ac.jp/pub/apache/$1";
push @mirrors, "ftp://apache.cs.utah.edu/apache.org/$1";
push @mirrors, "ftp://apache.mirrors.ovh.net/ftp.apache.org/dist/$1";
push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/apache/$1";
push @mirrors, "https://mirrors.ustc.edu.cn/apache/$1";
} elsif ($mirror =~ /^\@GITHUB\/(.+)$/) {
my $dir = $1;
my $i = 0;
# replace the 2nd '/' with '@' for jsDelivr mirror
push @mirrors, "https://cdn.jsdelivr.net/gh/". $dir =~ s{\/}{++$i == 2 ? '@' : $&}ger;
# give github a few more tries (different mirrors)
for (1 .. 5) {
push @mirrors, "https://raw.githubusercontent.com/$dir";
push @mirrors, "https://raw.githubusercontent.com/$1";
}
} elsif ($mirror =~ /^\@GNU\/(.+)$/) {
push @mirrors, "https://mirrors.cloud.tencent.com/gnu/$1";
push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnu/$1";
push @mirrors, "https://mirror.netcologne.de/gnu/$1";
push @mirrors, "http://ftp.kddilabs.jp/GNU/gnu/$1";
@ -266,6 +260,8 @@ foreach my $mirror (@ARGV) {
push @mirrors, "ftp://mirrors.rit.edu/gnu/$1";
push @mirrors, "ftp://download.xs4all.nl/pub/gnu/$1";
push @mirrors, "https://ftp.gnu.org/gnu/$1";
push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/gnu/$1";
push @mirrors, "https://mirrors.ustc.edu.cn/gnu/$1";
} elsif ($mirror =~ /^\@SAVANNAH\/(.+)$/) {
push @mirrors, "https://mirror.netcologne.de/savannah/$1";
push @mirrors, "https://mirror.csclub.uwaterloo.ca/nongnu/$1";
@ -282,7 +278,6 @@ foreach my $mirror (@ARGV) {
push @extra, "$extra[0]/longterm/v$1";
}
foreach my $dir (@extra) {
push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir";
push @mirrors, "https://cdn.kernel.org/pub/$dir";
push @mirrors, "https://download.xs4all.nl/ftp.kernel.org/pub/$dir";
push @mirrors, "https://mirrors.mit.edu/kernel/$dir";
@ -290,10 +285,11 @@ foreach my $mirror (@ARGV) {
push @mirrors, "http://www.ring.gr.jp/archives/linux/kernel.org/$dir";
push @mirrors, "ftp://ftp.riken.jp/Linux/kernel.org/$dir";
push @mirrors, "ftp://www.mirrorservice.org/sites/ftp.kernel.org/pub/$dir";
push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/kernel/$dir";
push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir";
}
} elsif ($mirror =~ /^\@GNOME\/(.+)$/) {
push @mirrors, "https://download.gnome.org/sources/$1";
push @mirrors, "https://mirrors.ustc.edu.cn/gnome/sources/$1";
push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnome/sources/$1";
push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1";
push @mirrors, "http://ftp.kaist.ac.kr/gnome/sources/$1";
@ -302,6 +298,7 @@ foreach my $mirror (@ARGV) {
push @mirrors, "http://ftp.belnet.be/ftp.gnome.org/sources/$1";
push @mirrors, "ftp://ftp.cse.buffalo.edu/pub/Gnome/sources/$1";
push @mirrors, "ftp://ftp.nara.wide.ad.jp/pub/X11/GNOME/sources/$1";
push @mirrors, "https://mirrors.ustc.edu.cn/gnome/sources/$1";
} else {
push @mirrors, $mirror;
}

View File

@ -4,7 +4,7 @@ use strict;
use warnings;
use Cwd;
my (%targets, %architectures);
my (%targets, %architectures, %kernels);
$ENV{'TOPDIR'} = Cwd::getcwd();
@ -13,7 +13,7 @@ sub parse_targetinfo {
my ($target_dir, $subtarget) = @_;
if (open M, "make -C '$target_dir' --no-print-directory DUMP=1 TARGET_BUILD=1 SUBTARGET='$subtarget' |") {
my ($target_name, $target_arch, @target_features);
my ($target_name, $target_arch, $target_kernel, $target_testing_kernel, @target_features);
while (defined(my $line = readline M)) {
chomp $line;
@ -23,19 +23,32 @@ sub parse_targetinfo {
elsif ($line =~ /^Target-Arch-Packages: (.+)$/) {
$target_arch = $1;
}
elsif ($line =~ /^Linux-Version: (\d\.\d+)\.\d+$/) {
$target_kernel = $1;
}
elsif ($line =~ /^Linux-Testing-Version: (\d\.\d+)\.\d+$/) {
$target_testing_kernel = $1;
}
elsif ($line =~ /^Target-Features: (.+)$/) {
@target_features = split /\s+/, $1;
}
elsif ($line =~ /^@\@$/) {
if ($target_name && $target_arch &&
if ($target_name && $target_arch && $target_kernel &&
!grep { $_ eq 'broken' or $_ eq 'source-only' } @target_features) {
$targets{$target_name} = $target_arch;
$architectures{$target_arch} ||= [];
push @{$architectures{$target_arch}}, $target_name;
$kernels{$target_name} ||= [];
push @{$kernels{$target_name}}, $target_kernel;
if ($target_testing_kernel) {
push @{$kernels{$target_name}}, $target_testing_kernel;
}
}
undef $target_name;
undef $target_arch;
undef $target_kernel;
undef $target_testing_kernel;
@target_features = ();
}
}
@ -85,7 +98,14 @@ elsif (@ARGV == 1 && $ARGV[0] eq 'architectures') {
printf "%s %s\n", $target_arch, join ' ', @{$architectures{$target_arch}};
}
}
elsif (@ARGV == 1 && $ARGV[0] eq 'kernels') {
get_targetinfo();
foreach my $target_name (sort keys %targets) {
printf "%s %s\n", $target_name, join ' ', @{$kernels{$target_name}};
}
}
else {
print "Usage: $0 targets\n";
print "Usage: $0 architectures\n";
print "Usage: $0 kernels\n";
}

View File

@ -61,7 +61,7 @@ env_init() {
mkdir -p "$ENVDIR" || error "Failed to create the environment directory"
cd "$ENVDIR" || error "Failed to switch to the environment directory"
[ -d .git ] || {
git init &&
git init -b master &&
touch .config &&
mkdir files &&
git add . &&

View File

@ -50,6 +50,7 @@ BIN_SPECS="
gdbserver: gdbserver
"
OVERWRITE_CONFIG=""
test_c() {
cat <<-EOT | "${CC:-false}" $CFLAGS -o /dev/null -x c - 2>/dev/null
@ -281,8 +282,11 @@ print_config() {
local mksubtarget
local target="$("$CC" $CFLAGS -dumpmachine)"
local version="$("$CC" $CFLAGS -dumpversion)"
local cpuarch="${target%%-*}"
local prefix="${CC##*/}"; prefix="${prefix%-*}-"
# get CC; strip version; strip gcc and add - suffix
local prefix="${CC##*/}"; prefix="${prefix%-$version}"; prefix="${prefix%-*}-"
local config="${0%/scripts/*}/.config"
# if no target specified, print choice list and exit
@ -317,9 +321,13 @@ print_config() {
fi
# bail out if there is a .config already
if [ -f "${0%/scripts/*}/.config" ]; then
echo "There already is a .config file, refusing to overwrite!" >&2
return 1
if [ -f "$config" ]; then
if [ "$OVERWRITE_CONFIG" == "" ]; then
echo "There already is a .config file, refusing to overwrite!" >&2
return 1
else
echo "There already is a .config file, trying to overwrite!"
fi
fi
case "$mktarget" in */*)
@ -327,8 +335,11 @@ print_config() {
mktarget="${mktarget%/*}"
;; esac
if [ ! -f "$config" ]; then
touch "$config"
fi
echo "CONFIG_TARGET_${mktarget}=y" > "$config"
echo "CONFIG_TARGET_${mktarget}=y" >> "$config"
if [ -n "$mksubtarget" ]; then
echo "CONFIG_TARGET_${mktarget}_${mksubtarget}=y" >> "$config"
@ -358,8 +369,18 @@ print_config() {
echo "CONFIG_TOOLCHAIN_PREFIX=\"$prefix\"" >> "$config"
echo "CONFIG_TARGET_NAME=\"$target\"" >> "$config"
if [ "$LIBC_TYPE" != glibc ]; then
echo "CONFIG_TOOLCHAIN_LIBC=\"$LIBC_TYPE\"" >> "$config"
if [ -f "$config" ]; then
sed -i '/CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_MUSL/d' "$config"
sed -i '/CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_GLIBC/d' "$config"
fi
if [ "$LIBC_TYPE" == glibc ]; then
echo "CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_GLIBC=y" >> "$config"
elif [ "$LIBC_TYPE" == musl ]; then
echo "CONFIG_EXTERNAL_TOOLCHAIN_LIBC_USE_MUSL=y" >> "$config"
else
echo "Can't detect LIBC type. Aborting!" >&2
return 1
fi
local lib
@ -452,6 +473,13 @@ probe_cpp() {
}
probe_libc() {
if [ -f $TOOLCHAIN/info.mk ]; then
LIBC_TYPE=$(grep LIBC_TYPE $TOOLCHAIN/info.mk | sed 's/LIBC_TYPE=//')
return 0
fi
echo "Warning! Can't find info.mk, trying to detect with alternative way."
if [ -z "$LIBC_TYPE" ]; then
if test_uclibc; then
LIBC_TYPE="uclibc"
@ -529,8 +557,13 @@ while [ -n "$1" ]; do
exit $?
;;
--overwrite-config)
OVERWRITE_CONFIG=y
;;
--config)
if probe_cc; then
probe_libc
print_config "$1"
exit $?
fi
@ -569,7 +602,9 @@ while [ -n "$1" ]; do
echo -e " Most commands also take a --cflags parameter which " >&2
echo -e " is used to specify C flags to be passed to the " >&2
echo -e " cross compiler when performing tests." >&2
echo -e " This paremter may be repeated multiple times." >&2
echo -e " This parameter may be repeated multiple times." >&2
echo -e " Use --overwrite-config before --config to overwrite" >&2
echo -e " an already present config with the required changes.">&2
exit 1
;;

98
scripts/ext-tools.sh Executable file
View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
TOOLS_TAR=""
HOST_BUILD_DIR=$(pwd)/"build_dir/host"
HOST_STAGING_DIR_STAMP=$(pwd)/"staging_dir/host/stamp"
refresh_timestamps() {
find "$1" -not -type l -print0 | xargs -0 touch
}
extract_prebuilt_tar() {
tar -xf "$1"
}
install_prebuilt_tools() {
extract_prebuilt_tar "$TOOLS_TAR"
if [ ! -d "$HOST_BUILD_DIR" ]; then
echo "Can't find Host Build Dir "$HOST_BUILD_DIR"" >&2
exit 1
fi
refresh_timestamps "$HOST_BUILD_DIR"
sleep 1
if [ ! -d "$HOST_STAGING_DIR_STAMP" ]; then
echo "Can't find Host Staging Dir Stamp "$HOST_STAGING_DIR_STAMP"" >&2
exit 1
fi
refresh_timestamps "$HOST_STAGING_DIR_STAMP"
return 0
}
while [ -n "$1" ]; do
arg="$1"; shift
case "$arg" in
--host-build-dir)
[ -d "$1" ] || {
echo "Directory '$1' does not exist." >&2
exit 1
}
HOST_BUILD_DIR="$(cd "$1"; pwd)"; shift
;;
--host-staging-dir-stamp)
[ -d "$1" ] || {
echo "Directory '$1' does not exist." >&2
exit 1
}
HOST_STAGING_DIR_STAMP="$(cd "$1"; pwd)"; shift
;;
--tools)
[ -f "$1" ] || {
echo "Tools tar file '$1' does not exist." >&2
exit 1
}
TOOLS_TAR="$1"; shift
install_prebuilt_tools
exit $?
;;
-h|--help)
me="$(basename "$0")"
echo -e "\nUsage:\n" >&2
echo -e " $me --host-build-dir {directory}" >&2
echo -e " Set to refresh timestamp of this build directory" >&2
echo -e " with --tools." >&2
echo -e " THIS OPTION MUST BE SET BEFORE --tools." >&2
echo -e " If not provided the default directory is:" >&2
echo -e " $(pwd)/build_dir/host\n" >&2
echo -e " $me --host-staging-dir-stamp {directory}" >&2
echo -e " Set to refresh staging timestamp present in this" >&2
echo -e " directory with --tools." >&2
echo -e " THIS OPTION MUST BE SET BEFORE --tools." >&2
echo -e " If not provided the default directory is:" >&2
echo -e " $(pwd)/staging_dir/host/stamp\n" >&2
echo -e " $me --tools {tar}" >&2
echo -e " Install the prebuilt tools present in the passed" >&2
echo -e " tar and prepare them." >&2
echo -e " To correctly use them it's needed to update the." >&2
echo -e " timestamp of each tools to skip recompilation.\n" >&2
echo -e " $me --help" >&2
echo -e " Display this help text and exit.\n\n" >&2
exit 1
;;
*)
echo "Unknown argument '$arg'" >&2
exec $0 --help
;;
esac
done
exec $0 --help

View File

@ -14,7 +14,7 @@ chdir $ENV{TOPDIR};
$ENV{GIT_CONFIG_PARAMETERS}="'core.autocrlf=false'";
$ENV{GREP_OPTIONS}="";
my $mk=`which gmake 2>/dev/null`; # select the right 'make' program
my $mk=`command -v gmake 2>/dev/null`; # select the right 'make' program
chomp($mk); # trim trailing newline
$mk or $mk = "make"; # default to 'make'
@ -167,8 +167,8 @@ my %update_method = (
'init' => "git clone '%s' '%s'",
'init_branch' => "git clone --branch '%s' '%s' '%s'",
'init_commit' => "git clone '%s' '%s' && cd '%s' && git checkout -b '%s' '%s' && cd -",
'update' => "git pull --ff",
'update_force' => "git pull --ff || (git reset --hard HEAD; git pull --ff; exit 1)",
'update' => "git pull --ff-only",
'update_force' => "git pull --ff-only || (git reset --hard HEAD; git pull --ff-only; exit 1)",
'post_update' => "git submodule update --init --recursive",
'controldir' => ".git",
'revision' => "git rev-parse --short HEAD | tr -d '\n'"},
@ -434,14 +434,16 @@ sub do_install_target($) {
$path =~ s/\/Makefile$//;
my $name = $path;
$name =~ s/.*\///;
my $dest = "./target/linux/$name";
my $dest = "./target/linux/feeds/$name";
-d "./target/linux/feeds" or mkdir "./target/linux/feeds";
-e $dest and do {
warn "Path $dest already exists";
return 1;
};
system("ln -sf ../../$path ./target/linux/");
system("ln -sf ../../../$path ./target/linux/feeds/");
} else {
warn "Target is not valid\n";
return 1;
@ -498,16 +500,34 @@ sub is_core_src($) {
sub install_target {
my $feed = shift;
my $name = shift;
my $force = shift;
$installed_targets{$name} and return 0;
$feed = lookup_target($feed, $name);
my $feed_name = $feed->[1];
$feed = $feed_cache{$feed->[1]}->[2];
-e "target/linux/feeds/$name" and return 0;
# enable force flag if feed src line was declared with --force
if (exists($feed->[3]{force})) {
$force = 1;
}
$feed = $feed_cache{$feed_name}->[2];
$feed or return 0;
my $target = $feed->{$name};
$target or return 0;
warn "Installing target '$name'\n";
if (-e "target/linux/$name") {
if ($force) {
warn "Overriding target '$name' with version from '$feed_name'\n";
} else {
warn "WARNING: Not overriding core target '$name'; use -f to force\n";
return 0;
}
} else {
warn "Installing target '$name'\n";
}
return do_install_target($target);
}
@ -618,7 +638,7 @@ sub install_target_or_package {
my $force = shift;
lookup_target($feed, $name) and do {
return install_target($feed, $name);
return install_target($feed, $name, $force);
};
lookup_src($feed, $name) and do {
@ -734,7 +754,7 @@ sub uninstall {
}
get_installed();
while ($name = shift @ARGV) {
my $target = "target/linux/$name";
my $target = "target/linux/feeds/$name";
-l "$target" and do {
uninstall_target($target);
$uninstall = 1;
@ -901,7 +921,7 @@ my %commands = (
'uninstall' => \&uninstall,
'feed_config' => \&feed_config,
'clean' => sub {
system("rm -rf ./feeds ./package/feeds");
system("rm -rf ./feeds ./package/feeds ./target/linux/feeds");
}
);

View File

@ -3,7 +3,6 @@
import argparse
from ftplib import FTP
from sys import argv
from os import stat
parser = argparse.ArgumentParser(description='Tool to boot AVM EVA ramdisk images.')

View File

@ -1,13 +0,0 @@
#!/bin/sh
TARGETS=$*
READELF="${READELF:-readelf}"
XARGS="${XARGS:-xargs -r}"
find $TARGETS -type f -a -exec file {} \; | \
sed -n -e 's/^\(.*\):.*ELF.*\(executable\|shared object\).*,.*/\1/p' | \
$XARGS -n1 $READELF -l | grep 'Requesting' | cut -d':' -f2 | tr -d ' ]' | \
$XARGS basename
cd `dirname ${0}`
./gen-dependencies.sh ${TARGETS}

View File

@ -26,15 +26,33 @@ KERNELSIZE="$2"
ROOTFSOFFSET="$(($3 / 512))"
ROOTFSSIZE="$(($4 / 512))"
# Using mcopy -s ... is using READDIR(3) to iterate through the directory
# entries, hence they end up in the FAT filesystem in traversal order which
# breaks reproducibility.
# Implement recursive copy with reproducible order.
dos_dircopy() {
local entry
local baseentry
for entry in "$1"/* ; do
if [ -f "$entry" ]; then
mcopy -i "$OUTPUT.kernel" "$entry" ::"$2"
elif [ -d "$entry" ]; then
baseentry="$(basename "$entry")"
mmd -i "$OUTPUT.kernel" ::"$2""$baseentry"
dos_dircopy "$entry" "$2""$baseentry"/
fi
done
}
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
if [ -n "$GUID" ]; then
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$((ROOTFSOFFSET + ROOTFSSIZE))" conv=notrunc count="$sect"
mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$((KERNELSIZE / 1024))"
mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
mkfs.fat --invariant -n kernel -C "$OUTPUT.kernel" -S 512 "$((KERNELSIZE / 1024))"
LC_ALL=C dos_dircopy "$KERNELDIR" /
else
make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
make_ext4fs -J -L kernel -l "$KERNELSIZE" ${SOURCE_DATE_EPOCH:+-T ${SOURCE_DATE_EPOCH}} "$OUTPUT.kernel" "$KERNELDIR"
fi
dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
rm -f "$OUTPUT.kernel"

View File

@ -58,7 +58,8 @@ pkg_appears_sane() {
rm "$CONTROL"/conffiles
if [ -f "$CONTROL"/conffiles.resolved ]; then
mv "$CONTROL"/conffiles.resolved "$CONTROL"/conffiles
LC_ALL=C sort -o "$CONTROL"/conffiles "$CONTROL"/conffiles.resolved
rm "$CONTROL"/conffiles.resolved
chmod 0644 "$CONTROL"/conffiles
fi
fi
@ -178,20 +179,20 @@ for file_mode in $file_modes; do
chown "$uid:$gid" "$pkg_dir/$path"
chmod "$mode" "$pkg_dir/$path"
done
$TAR -X "$tmp_dir"/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | gzip -n - > "$tmp_dir"/data.tar.gz
$TAR -X "$tmp_dir"/tarX --format=gnu --numeric-owner --sort=name -cpf - --mtime="$TIMESTAMP" . | gzip -n - > "$tmp_dir"/data.tar.gz
installed_size=$(stat -c "%s" "$tmp_dir"/data.tar.gz)
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
"$pkg_dir"/$CONTROL/control
( cd "$pkg_dir"/$CONTROL && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | gzip -n - > "$tmp_dir"/control.tar.gz )
( cd "$pkg_dir"/$CONTROL && $TAR --format=gnu --numeric-owner --sort=name -cf - --mtime="$TIMESTAMP" . | gzip -n - > "$tmp_dir"/control.tar.gz )
rm "$tmp_dir"/tarX
echo "2.0" > "$tmp_dir"/debian-binary
pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
rm -f "$pkg_file"
( cd "$tmp_dir" && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | gzip -n - > "$pkg_file" )
( cd "$tmp_dir" && $TAR --format=gnu --numeric-owner --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | gzip -n - > "$pkg_file" )
rm "$tmp_dir"/debian-binary "$tmp_dir"/data.tar.gz "$tmp_dir"/control.tar.gz
rmdir "$tmp_dir"

View File

@ -11,11 +11,11 @@ if len(argv) != 2:
exit(1)
json_path = Path(argv[1])
bin_dir = Path(getenv("BIN_DIR"))
image_file = bin_dir / getenv("DEVICE_IMG_NAME")
file_path = Path(getenv("FILE_DIR")) / getenv("FILE_NAME")
if not image_file.is_file():
print("Skip JSON creation for non existing image ", image_file)
if not file_path.is_file():
print("Skip JSON creation for non existing file", file_path)
exit(0)
@ -37,23 +37,30 @@ def get_titles():
device_id = getenv("DEVICE_ID")
image_hash = hashlib.sha256(image_file.read_bytes()).hexdigest()
hash_file = hashlib.sha256(file_path.read_bytes()).hexdigest()
image_info = {
if file_path.with_suffix(file_path.suffix + ".sha256sum").exists():
hash_unsigned = (
file_path.with_suffix(file_path.suffix + ".sha256sum").read_text().strip()
)
else:
hash_unsigned = hash_file
file_info = {
"metadata_version": 1,
"target": "{}/{}".format(getenv("TARGET"), getenv("SUBTARGET")),
"version_code": getenv("VERSION_CODE"),
"version_number": getenv("VERSION_NUMBER"),
"source_date_epoch": getenv("SOURCE_DATE_EPOCH"),
"source_date_epoch": int(getenv("SOURCE_DATE_EPOCH")),
"profiles": {
device_id: {
"image_prefix": getenv("DEVICE_IMG_PREFIX"),
"images": [
{
"type": getenv("IMAGE_TYPE"),
"filesystem": getenv("IMAGE_FILESYSTEM"),
"name": getenv("DEVICE_IMG_NAME"),
"sha256": image_hash,
"type": getenv("FILE_TYPE"),
"name": getenv("FILE_NAME"),
"sha256": hash_file,
"sha256_unsigned": hash_unsigned,
}
],
"device_packages": getenv("DEVICE_PACKAGES").split(),
@ -63,4 +70,9 @@ image_info = {
},
}
json_path.write_text(json.dumps(image_info, separators=(",", ":")))
if getenv("FILE_FILESYSTEM"):
file_info["profiles"][device_id]["images"][0]["filesystem"] = getenv(
"FILE_FILESYSTEM"
)
json_path.write_text(json.dumps(file_info, separators=(",", ":")))

View File

@ -7,7 +7,7 @@ from sys import argv
import json
if len(argv) != 2:
print("JSON info files script requires ouput file as argument")
print("JSON info files script requires output file as argument")
exit(1)
output_path = Path(argv[1])
@ -42,7 +42,7 @@ for json_file in work_dir.glob("*.json"):
output["profiles"][device_id]["images"].extend(profile["images"])
# make image lists unique by name, keep last/latest
for device_id, profile in output["profiles"].items():
for device_id, profile in output.get("profiles", {}).items():
profile["images"] = list({e["name"]: e for e in profile["images"]}.values())

View File

@ -11,11 +11,11 @@
# This is appended to the factory image and is tested by the Linksys Upgrader - as observed in civic.
# The footer is 256 bytes. The format is:
# .LINKSYS. This is detected by the Linksys upgrader before continuing with upgrade. (9 bytes)
# <VERSION> The version number of upgrade. Not checked so use arbitary value (8 bytes)
# <VERSION> The version number of upgrade. Not checked so use arbitrary value (8 bytes)
# <TYPE> Model of target device, padded (0x20) to (15 bytes)
# <CRC> CRC checksum of the image to flash (8 byte)
# <padding> Padding (0x20) (7 bytes)
# <signature> Signature of signer. Not checked so use Arbitary value (16 bytes)
# <signature> Signature of signer. Not checked so use arbitrary value (16 bytes)
# <padding> Padding (0x00) (192 bytes)
# 0x0A (1 byte)

View File

@ -290,17 +290,24 @@ sub parse_package_metadata($) {
};
/^Config:\s*(.*)\s*$/ and $pkg->{config} = "$1\n".get_multiline(*FILE, "\t");
/^Prereq-Check:/ and $pkg->{prereq} = 1;
/^Maintainer: \s*(.+)\s*$/ and $pkg->{maintainer} = [ split /, /, $1 ];
/^Require-User:\s*(.*?)\s*$/ and do {
my @ugspecs = split /\s+/, $1;
for my $ugspec (@ugspecs) {
my @ugspec = split /:/, $ugspec, 2;
my @ugspec = split /:/, $ugspec, 3;
if ($ugspec[0]) {
parse_package_metadata_usergroup($src->{makefile}, "user", \%usernames, \%userids, $ugspec[0]) or return 0;
}
if ($ugspec[1]) {
parse_package_metadata_usergroup($src->{makefile}, "group", \%groupnames, \%groupids, $ugspec[1]) or return 0;
}
if ($ugspec[2]) {
my @addngroups = split /,/, $ugspec[2];
for my $addngroup (@addngroups) {
parse_package_metadata_usergroup($src->{makefile}, "group", \%groupnames, \%groupids, $addngroup) or return 0;
}
}
}
};
}

View File

@ -105,7 +105,6 @@ be32enc(void *buf, uint32_t u)
p[2] = ((uint8_t) ((u >> 8) & 0xff));
p[3] = ((uint8_t) (u & 0xff));
}
#endif
static void
be64enc(void *buf, uint64_t u)
@ -132,6 +131,7 @@ be32dec(const void *buf)
return (((uint32_t) be16dec(p)) << 16) | be16dec(p + 2);
}
#endif
#define MD5_DIGEST_LENGTH 16

38
scripts/mkits-zyxel-fit.sh Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
#
# Licensed under the terms of the GNU GPL License version 2 or later.
# Author: David Bauer <mail@david-bauer.net>, based on mkits-zyxel-factory.sh.
usage() {
echo "Usage: `basename $0` output file compat-models"
exit 1
}
# We need at least 3 arguments
[ "$#" -lt 3 ] && usage
# Target output file
OUTPUT="$1"; shift
FILE="$1"; shift
MODELS="$1"; shift
# Create a default, fully populated DTS file
echo "\
/dts-v1/;
/ {
description = \"Zyxel FIT (Flattened Image Tree)\";
compat-models = [${MODELS}];
#address-cells = <1>;
images {
firmware {
data = /incbin/(\"${FILE}\");
type = \"firmware\";
compression = \"none\";
hash@1 {
algo = \"sha1\";
};
};
};
};" > ${OUTPUT}

View File

@ -32,12 +32,14 @@ usage() {
printf "\n\t-d ==> include Device Tree Blob 'dtb'"
printf "\n\t-r ==> include RootFS blob 'rootfs'"
printf "\n\t-H ==> specify hash algo instead of SHA1"
printf "\n\t-l ==> legacy mode character (@ etc otherwise -)"
printf "\n\t-o ==> create output file 'its_file'"
printf "\n\t-O ==> create config with dt overlay 'name:dtb'"
printf "\n\t\t(can be specified more than once)\n"
exit 1
}
REFERENCE_CHAR='-'
FDTNUM=1
ROOTFSNUM=1
INITRDNUM=1
@ -46,7 +48,7 @@ LOADABLES=
DTOVERLAY=
DTADDR=
while getopts ":A:a:c:C:D:d:e:f:i:k:n:o:O:v:r:H:" OPTION
while getopts ":A:a:c:C:D:d:e:f:i:k:l:n:o:O:v:r:H:" OPTION
do
case $OPTION in
A ) ARCH=$OPTARG;;
@ -59,6 +61,7 @@ do
f ) COMPATIBLE=$OPTARG;;
i ) INITRD=$OPTARG;;
k ) KERNEL=$OPTARG;;
l ) REFERENCE_CHAR=$OPTARG;;
n ) FDTNUM=$OPTARG;;
o ) OUTPUT=$OPTARG;;
O ) DTOVERLAY="$DTOVERLAY ${OPTARG}";;
@ -91,7 +94,7 @@ fi
# Conditionally create fdt information
if [ -n "${DTB}" ]; then
FDT_NODE="
fdt-$FDTNUM {
fdt${REFERENCE_CHAR}$FDTNUM {
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\";
${COMPATIBLE_PROP}
data = /incbin/(\"${DTB}\");
@ -107,12 +110,12 @@ if [ -n "${DTB}" ]; then
};
};
"
FDT_PROP="fdt = \"fdt-$FDTNUM\";"
FDT_PROP="fdt = \"fdt${REFERENCE_CHAR}$FDTNUM\";"
fi
if [ -n "${INITRD}" ]; then
INITRD_NODE="
initrd-$INITRDNUM {
initrd${REFERENCE_CHAR}$INITRDNUM {
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} initrd\";
${COMPATIBLE_PROP}
data = /incbin/(\"${INITRD}\");
@ -127,14 +130,14 @@ if [ -n "${INITRD}" ]; then
};
};
"
INITRD_PROP="ramdisk=\"initrd-${INITRDNUM}\";"
INITRD_PROP="ramdisk=\"initrd${REFERENCE_CHAR}${INITRDNUM}\";"
fi
if [ -n "${ROOTFS}" ]; then
dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync
ROOTFS_NODE="
rootfs-$ROOTFSNUM {
rootfs${REFERENCE_CHAR}$ROOTFSNUM {
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} rootfs\";
${COMPATIBLE_PROP}
data = /incbin/(\"${ROOTFS}.pagesync\");
@ -149,7 +152,7 @@ if [ -n "${ROOTFS}" ]; then
};
};
"
LOADABLES="${LOADABLES:+$LOADABLES, }\"rootfs-${ROOTFSNUM}\""
LOADABLES="${LOADABLES:+$LOADABLES, }\"rootfs${REFERENCE_CHAR}${ROOTFSNUM}\""
fi
# add DT overlay blobs
@ -184,8 +187,8 @@ OVCONFIGS=""
config-$ovname {
description = \"OpenWrt ${DEVICE} with $ovname\";
kernel = \"kernel-1\";
fdt = \"fdt-$FDTNUM\", \"$ovnode\";
kernel = \"kernel${REFERENCE_CHAR}1\";
fdt = \"fdt${REFERENCE_CHAR}$FDTNUM\", \"$ovnode\";
${LOADABLES:+loadables = ${LOADABLES};}
${COMPATIBLE_PROP}
${INITRD_PROP}
@ -201,7 +204,7 @@ DATA="/dts-v1/;
#address-cells = <1>;
images {
kernel-1 {
kernel${REFERENCE_CHAR}1 {
description = \"${ARCH_UPPER} OpenWrt Linux-${VERSION}\";
data = /incbin/(\"${KERNEL}\");
type = \"kernel\";
@ -227,7 +230,7 @@ ${ROOTFS_NODE}
default = \"${CONFIG}\";
${CONFIG} {
description = \"OpenWrt ${DEVICE}\";
kernel = \"kernel-1\";
kernel = \"kernel${REFERENCE_CHAR}1\";
${FDT_PROP}
${LOADABLES:+loadables = ${LOADABLES};}
${COMPATIBLE_PROP}

View File

@ -0,0 +1,68 @@
#!/usr/bin/env python3
import argparse
import re
import struct
import subprocess
import zlib
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--input-file', type=str, required=True)
parser.add_argument('--output-file', type=str, required=True)
parser.add_argument('--model', type=str, required=True)
parser.add_argument('--region', type=str, required=True)
parser.add_argument('--version', type=str, required=True)
parser.add_argument('--encryption-block-size', type=str, required=True)
parser.add_argument('--openssl-bin', type=str, required=True)
parser.add_argument('--key', type=str, required=True)
parser.add_argument('--iv', type=str, required=True)
args = parser.parse_args()
assert re.match(r'V[0-9]\.[0-9]\.[0-9]\.[0-9]',
args.version), 'Version must start with Vx.x.x.x'
encryption_block_size = int(args.encryption_block_size, 0)
assert (encryption_block_size > 0 and encryption_block_size % 16 ==
0), 'Encryption block size must be a multiple of the AES block size (16)'
image = open(args.input_file, 'rb').read()
image_enc = []
for i in range(0, len(image), encryption_block_size):
chunk = image[i:i + encryption_block_size]
chunk += b'\x00' * ((-len(chunk)) % 16) # pad to AES block size (16)
res = subprocess.run([
args.openssl_bin,
'enc',
'-aes-256-cbc',
'-nosalt',
'-nopad',
'-K', args.key,
'-iv', args.iv
],
check=True, input=chunk, stdout=subprocess.PIPE)
image_enc.append(res.stdout)
image_enc = b''.join(image_enc)
image_with_header = struct.pack(
'>32s32s64s64s64s256s12sII',
args.model.encode('ascii'),
args.region.encode('ascii'),
args.version.encode('ascii'),
b'Thu Jan 1 00:00:00 1970', # static date for reproducibility
b'', # reserved
b'', # RSA signature - omitted for now
b'encrpted_img',
len(image_enc),
encryption_block_size,
) + image_enc
checksum = zlib.crc32(image_with_header, 0xffffffff) ^ 0xffffffff
with open(args.output_file, 'wb') as outfile:
outfile.write(image_with_header)
outfile.write(struct.pack('>I', checksum))
if __name__ == "__main__":
main()

View File

@ -585,6 +585,40 @@ sub gen_usergroup_list() {
}
}
sub gen_package_manifest_json() {
my $json;
parse_package_metadata($ARGV[0]) or exit 1;
foreach my $name (sort {uc($a) cmp uc($b)} keys %package) {
my %depends;
my $pkg = $package{$name};
foreach my $dep (@{$pkg->{depends} || []}) {
if ($dep =~ m!^\+?(?:[^:]+:)?([^@]+)$!) {
$depends{$1}++;
}
}
my @depends = sort keys %depends;
my $pkg_deps = join ' ', map { qq/"$_",/ } @depends;
$pkg_deps =~ s/\,$//;
my $pkg_maintainer = join ' ', map { qq/"$_",/ } @{$pkg->{maintainer} || []};
$pkg_maintainer =~ s/\,$//;
$json = <<"END_JSON";
${json}{
"name":"$name",
"version":"$pkg->{version}",
"category":"$pkg->{category}",
"license":"$pkg->{license}",
"maintainer": [$pkg_maintainer],
"depends":[$pkg_deps]},
END_JSON
}
$json =~ s/[\n\r]//g;
$json =~ s/\,$//;
print "[$json]";
}
sub parse_command() {
GetOptions("ignore=s", \@ignore);
my $cmd = shift @ARGV;
@ -594,6 +628,7 @@ sub parse_command() {
/^kconfig/ and return gen_kconfig_overrides();
/^source$/ and return gen_package_source();
/^pkgaux$/ and return gen_package_auxiliary();
/^pkgmanifestjson$/ and return gen_package_manifest_json();
/^license$/ and return gen_package_license(0);
/^licensefull$/ and return gen_package_license(1);
/^usergroup$/ and return gen_usergroup_list();
@ -606,6 +641,7 @@ Available Commands:
$0 kconfig [file] [config] [patchver] Kernel config overrides
$0 source [file] Package source file information
$0 pkgaux [file] Package auxiliary variables in makefile format
$0 pkgmanifestjson [file] Package manifests in JSON format
$0 license [file] Package license information
$0 licensefull [file] Package license information (full list)
$0 usergroup [file] Package usergroup allocation list

View File

@ -2,7 +2,7 @@
function usage {
echo "Usage: prepare_image image_type kernel_image rootfs_image header_size"
echo "Padd root and kernel image to the correct size and append the jffs2 start marker as needed"
echo "Pad root and kernel image to the correct size and append the jffs2 start marker as needed"
exit 1
}

View File

@ -27,6 +27,7 @@ find $TARGETS -type f -a -exec file {} \; | \
while read F S; do
echo "$SELF: $F: $S"
[ "${S}" = "relocatable" ] && {
[ "${F##*.}" == "o" ] && continue
eval "$STRIP_KMOD $F"
} || {
b=$(stat -c '%a' $F)

121
scripts/sercomm-kernel-header.py Executable file
View File

@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""
# SPDX-License-Identifier: GPL-2.0-or-later
#
# sercomm-kernel-header.py: Creates Sercomm kernel header
#
# Copyright © 2022 Mikhail Zhilkin
"""
import argparse
import binascii
import os
import struct
KERNEL_HEADER_SIZE = 0x100
PADDING = 0xff
ROOTFS_FAKE_HEADER = "UBI#"
def auto_int(x):
return int(x, 0)
def create_kernel_header(args):
out_file = open(args.header_file, "wb")
header = get_kernel_header(args)
out_file.write(header)
out_file.close()
def get_kernel_header(args):
header = bytearray([PADDING] * KERNEL_HEADER_SIZE)
struct.pack_into('<L', header, 0xc, 0xffffff02)
struct.pack_into('<L', header, 0x1c, 0x0)
struct.pack_into('<L', header, 0x34, 0x0)
struct.pack_into('<L', header, 0x10, args.kernel_offset)
struct.pack_into('<L', header, 0x28, args.rootfs_offset)
if (args.rootfs_file):
if (args.rootfs_checking_size):
rootfs_size = args.rootfs_checking_size
else:
rootfs_size = os.path.getsize(args.rootfs_file)
buf = open(args.rootfs_file,'rb').read(rootfs_size)
crc = binascii.crc32(buf) & 0xffffffff
else:
rootfs_size = len(ROOTFS_FAKE_HEADER)
crc = binascii.crc32(str.encode(ROOTFS_FAKE_HEADER)) & \
0xffffffff
struct.pack_into('<L', header, 0x2c, rootfs_size)
struct.pack_into('<L', header, 0x30, crc)
rootfs_end_offset = args.rootfs_offset + rootfs_size
struct.pack_into('<L', header, 0x4, rootfs_end_offset)
kernel_size = os.path.getsize(args.kernel_file)
struct.pack_into('<L', header, 0x14, kernel_size)
buf = open(args.kernel_file,'rb').read()
crc = binascii.crc32(buf) & 0xffffffff
struct.pack_into('<L', header, 0x18, crc)
crc = binascii.crc32(header) & 0xffffffff
struct.pack_into('<L', header, 0x8, crc)
struct.pack_into('<L', header, 0x0, 0x726553)
return header
def main():
global args
parser = argparse.ArgumentParser(description='This script generates \
a kernel header for the Sercomm mt7621 devices')
parser.add_argument('--kernel-image',
dest='kernel_file',
action='store',
type=str,
help='Path to a Kernel binary image')
parser.add_argument('--kernel-offset',
dest='kernel_offset',
action='store',
type=auto_int,
help='Kernel offset')
parser.add_argument('--rootfs-offset',
dest='rootfs_offset',
action='store',
type=auto_int,
help='RootFS offset')
parser.add_argument('--output-header',
dest='header_file',
action='store',
type=str,
help='Output kernel header file')
parser.add_argument('--rootfs-image',
dest='rootfs_file',
action='store',
type=str,
help='Path to RootFS binary image (optional)')
parser.add_argument('--rootfs-checking-size',
dest='rootfs_checking_size',
action='store',
type=auto_int,
help='Bytes count for CRC calculation (optional)')
args = parser.parse_args()
if ((not args.kernel_file) or
(not args.kernel_offset) or
(not args.rootfs_offset) or
(not args.header_file)):
parser.print_help()
exit()
create_kernel_header(args)
main()

View File

@ -1,122 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2021 Mikhail Zhilkin <csharper2005@gmail.com>
#
###
### sercomm-kernel.sh - calculates and appends a special kernel header.
### Intended for some Sercomm devices (e.g., Beeline
### SmartBox GIGA, Beeline SmartBox Turbo+, Sercomm
### S3).
#
# Credits to @kar200 for the header description. More details are here:
# https://forum.openwrt.org/t/add-support-for-sercomm-s3-on-stock-uboot
#
if [ $# -ne 3 ]; then
echo "SYNTAX: $0 <kernel> <kernel_offset> <rootfs_offset>"
exit 1
fi
FILE_TMP=$1.shdr
KERNEL_IMG=$1
KERNEL_OFFSET=$2
ROOTFS_OFFSET=$3
# Sercomm HDR (0x53657200), 0xffffffff for hdr crc32 calc
hdr_sign_offs=0x0
hdr_sign_val=0x53657200
# Absoulte lenght for Sercomm footer
hdr_footer_size_offs=0x4
hdr_footer_size_val=
# Header checksum. 0xffffffff for hdr crc32 calc
hdr_head_chksum_offs=0x8
hdr_head_chksum_val=
# Magic constant (0x2ffffff)
hdr_int04_offs=0xc
hdr_int04_val=0x2ffffff
# Kernel flash offset
hdr_kern_offs_offs=0x10
hdr_kern_offs_val=$KERNEL_OFFSET
# Kernel lenght
hdr_kern_len_offs=0x14
hdr_kern_len_val=
# Kernel checksum
hdr_kern_chksum_offs=0x18
hdr_kern_chksum_val=
# Magic constant (0x0)
hdr_int08_offs=0x1c
hdr_int08_val=0x0
# Rootfs flash offset
hdr_rootfs_offs_offs=0x28
hdr_rootfs_offs_val=$ROOTFS_OFFSET
# Rootfs flash lenght. We're checking only first 4 bytes
hdr_rootfs_len_offs=0x2c
hdr_rootfs_len_val=0x4
# Rootfs checksum. Checksum is a constant for UBI (first 4 bytes)
hdr_rootfs_chksum_offs=0x30
hdr_rootfs_chksum_val=0x1cfc552d
# Magic constant (0x0)
hdr_int10_offs=0x34
hdr_int10_val=0x0
pad_zeros () {
awk '{ printf "%8s\n", $0 }' | sed 's/ /0/g'
}
# Remove leading 0x
trim_hx () {
printf "%x\n" $1 | pad_zeros
}
# Change endian
swap_hx () {
pad_zeros | awk '{for (i=7;i>=1;i=i-2) printf "%s%s", \
substr($1,i,2), (i>1?"":"\n")}'
}
# Check file size
fsize () {
printf "%x\n" `stat -c "%s" $1`
}
# Calculate checksum
chksum () {
dd if=$1 2>/dev/null | gzip -c | tail -c 8 | od -An -tx4 -N4 \
--endian=big | tr -d ' \n' | pad_zeros
}
# Write 4 bytes in the header by offset
write_hdr () {
echo -ne "$(echo $1 | sed 's/../\\x&/g')" | dd of=$FILE_TMP bs=1 \
seek=$(($2)) count=4 conv=notrunc status=none 2>/dev/null
}
# Pad a new header with 0xff
dd if=/dev/zero ibs=1 count=256 status=none | tr "\000" "\377" > \
$FILE_TMP 2>/dev/null
# Write constants
write_hdr $(trim_hx $hdr_int04_val) $hdr_int04_offs
write_hdr $(trim_hx $hdr_int08_val) $hdr_int08_offs
write_hdr $(trim_hx $hdr_int10_val) $hdr_int10_offs
# Write footer data
hdr_footer_size_val=$(($hdr_rootfs_offs_val + $hdr_rootfs_len_val))
write_hdr $(trim_hx $hdr_footer_size_val | swap_hx) $hdr_footer_size_offs
# Write kernel data
write_hdr $(trim_hx $hdr_kern_offs_val | swap_hx) $hdr_kern_offs_offs
hdr_kern_len_val=$(fsize $KERNEL_IMG | pad_zeros)
write_hdr $(echo $hdr_kern_len_val | swap_hx) $hdr_kern_len_offs
hdr_kern_chksum_val=$(chksum $KERNEL_IMG)
write_hdr $hdr_kern_chksum_val $hdr_kern_chksum_offs
# Write rootfs data
write_hdr $(trim_hx $hdr_rootfs_offs_val | swap_hx) $hdr_rootfs_offs_offs
write_hdr $(trim_hx $hdr_rootfs_len_val | swap_hx) $hdr_rootfs_len_offs
write_hdr $(trim_hx $hdr_rootfs_chksum_val) $hdr_rootfs_chksum_offs
# Write header checksum
hdr_head_chksum_val=$(chksum $FILE_TMP)
write_hdr $hdr_head_chksum_val $hdr_head_chksum_offs
# Place Sercomm signature
write_hdr $(trim_hx $hdr_sign_val) $hdr_sign_offs
dd if=$KERNEL_IMG >> $FILE_TMP
mv $FILE_TMP $KERNEL_IMG

102
scripts/sercomm-pid.py Executable file
View File

@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""
# SPDX-License-Identifier: GPL-2.0-or-later
#
# sercomm-pid.py: Creates Sercomm device PID
#
# Copyright © 2022 Mikhail Zhilkin
"""
import argparse
import binascii
import struct
PID_SIZE = 0x70
PADDING = 0x30
PADDING_TAIL = 0x0
def auto_int(x):
return int(x, 0)
def create_pid_file(args):
pid_file = open(args.pid_file, "wb")
buf = get_pid(args)
pid_file.write(buf)
pid_file.close()
def get_pid(args):
buf = bytearray([PADDING] * PID_SIZE)
enc = args.hw_version.rjust(8, '0').encode('ascii')
struct.pack_into('>8s', buf, 0x0, enc)
enc = binascii.hexlify(args.hw_id.encode())
struct.pack_into('>6s', buf, 0x8, enc)
enc = args.sw_version.rjust(4, '0').encode('ascii')
struct.pack_into('>4s', buf, 0x64, enc)
if (args.extra_padd_size):
tail = bytearray([PADDING_TAIL] * args.extra_padd_size)
if (args.extra_padd_byte):
struct.pack_into ('<i', tail, 0x0,
args.extra_padd_byte)
buf += tail
return buf
def main():
global args
parser = argparse.ArgumentParser(description='This script \
generates firmware PID for the Sercomm-based devices')
parser.add_argument('--hw-version',
dest='hw_version',
action='store',
type=str,
help='Sercomm hardware version')
parser.add_argument('--hw-id',
dest='hw_id',
action='store',
type=str,
help='Sercomm hardware ID')
parser.add_argument('--sw-version',
dest='sw_version',
action='store',
type=str,
help='Sercomm software version')
parser.add_argument('--pid-file',
dest='pid_file',
action='store',
type=str,
help='Output PID file')
parser.add_argument('--extra-padding-size',
dest='extra_padd_size',
action='store',
type=auto_int,
help='Size of extra NULL padding at the end of the file \
(optional)')
parser.add_argument('--extra-padding-first-byte',
dest='extra_padd_byte',
action='store',
type=auto_int,
help='First byte of extra padding (optional)')
args = parser.parse_args()
if ((not args.hw_version) or
(not args.hw_id) or
(not args.sw_version) or
(not args.pid_file)):
parser.print_help()
exit()
create_pid_file(args)
main()

View File

@ -3,12 +3,12 @@
# directory where search for images
TOP_DIR="${TOP_DIR:-./bin/targets}"
# key to sign images
BUILD_KEY="${BUILD_KEY:-key-build}" # TODO unifiy naming?
BUILD_KEY="${BUILD_KEY:-key-build}" # TODO unify naming?
# remove other signatures (added e.g. by buildbot)
REMOVE_OTER_SIGNATURES="${REMOVE_OTER_SIGNATURES:-1}"
# find all sysupgrade images in TOP_DIR
# factory images don't need signatures as non OpenWrt system doen't check them anyway
# factory images don't need signatures as non OpenWrt system doesn't check them anyway
for image in $(find $TOP_DIR -type f -name "*-sysupgrade.bin"); do
# check if image actually support metadata
if fwtool -i /dev/null "$image"; then

View File

@ -7,9 +7,9 @@
###
### The script compares locally compiled package with the package indexes
### available upstream. This way the storage impact of optimizations or
### feature modifiactions is easy to see.
### feature modifications is easy to see.
###
### If no environmental variables are set the scritp reads the current
### If no environmental variables are set the script reads the current
### .config file. The evaluated env variables are the following:
###
### TARGET SUBTARGET ARCH PACKAGES BIN_DIR BASE_URL CHECK_INSTALLED

View File

@ -772,7 +772,7 @@ sub writeOutFirmware {
$_->{'name'}, $filename);
}
# If the next parition is before the end of the current image, then rewind.
# If the next partition is before the end of the current image, then rewind.
elsif ($_->{'offset'} < $end_point) {
$debug and printf("Rewound %s before <%s> in \"%s\"\n",
(($end_point - $_->{'offset'}) >= $block_size ?
@ -971,7 +971,7 @@ if (!GetOptions("d|debug" => \$debug,
print " [-b|--redboot] <file> Input/Output RedBoot filename\n";
print " [-s|--sysconf] <file> Input/Output SysConf filename\n";
print " [-L|--loader] <file> Second stage boot loader filename\n";
print " [-k|--kernel] <file> Input/Ouptut Kernel filename\n";
print " [-k|--kernel] <file> Input/Output Kernel filename\n";
print " [-r|--ramdisk] <file> Input/Output Ramdisk filename(s)\n";
print " [-f|--fisdir] <file> Input/Output FIS directory filename\n";
print " [-m|--microcode] <file> Input/Output Microcode filename\n";

View File

@ -10,43 +10,44 @@ sub target_config_features(@) {
while ($_ = shift @_) {
/^arm_v(\w+)$/ and $ret .= "\tselect arm_v$1\n";
/^broken$/ and $ret .= "\tdepends on BROKEN\n";
/^audio$/ and $ret .= "\tselect AUDIO_SUPPORT\n";
/^boot-part$/ and $ret .= "\tselect USES_BOOT_PART\n";
/^broken$/ and $ret .= "\tdepends on BROKEN\n";
/^cpiogz$/ and $ret .= "\tselect USES_CPIOGZ\n";
/^display$/ and $ret .= "\tselect DISPLAY_SUPPORT\n";
/^dt$/ and $ret .= "\tselect USES_DEVICETREE\n";
/^gpio$/ and $ret .= "\tselect GPIO_SUPPORT\n";
/^pci$/ and $ret .= "\tselect PCI_SUPPORT\n";
/^pcie$/ and $ret .= "\tselect PCIE_SUPPORT\n";
/^usb$/ and $ret .= "\tselect USB_SUPPORT\n";
/^usbgadget$/ and $ret .= "\tselect USB_GADGET_SUPPORT\n";
/^pcmcia$/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
/^pwm$/ and $ret .= "\select PWM_SUPPORT\n";
/^rtc$/ and $ret .= "\tselect RTC_SUPPORT\n";
/^squashfs$/ and $ret .= "\tselect USES_SQUASHFS\n";
/^dt-overlay$/ and $ret .= "\tselect HAS_DT_OVERLAY_SUPPORT\n";
/^emmc$/ and $ret .= "\tselect EMMC_SUPPORT\n";
/^ext4$/ and $ret .= "\tselect USES_EXT4\n";
/^fpu$/ and $ret .= "\tselect HAS_FPU\n";
/^gpio$/ and $ret .= "\tselect GPIO_SUPPORT\n";
/^jffs2$/ and $ret .= "\tselect USES_JFFS2\n";
/^jffs2_nand$/ and $ret .= "\tselect USES_JFFS2_NAND\n";
/^ext4$/ and $ret .= "\tselect USES_EXT4\n";
/^targz$/ and $ret .= "\tselect USES_TARGZ\n";
/^cpiogz$/ and $ret .= "\tselect USES_CPIOGZ\n";
/^minor$/ and $ret .= "\tselect USES_MINOR\n";
/^ubifs$/ and $ret .= "\tselect USES_UBIFS\n";
/^fpu$/ and $ret .= "\tselect HAS_FPU\n";
/^spe_fpu$/ and $ret .= "\tselect HAS_SPE_FPU\n";
/^ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n";
/^separate_ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n\tselect USES_SEPARATE_INITRAMFS\n";
/^powerpc64$/ and $ret .= "\tselect powerpc64\n";
/^nommu$/ and $ret .= "\tselect NOMMU\n";
/^mips16$/ and $ret .= "\tselect HAS_MIPS16\n";
/^rfkill$/ and $ret .= "\tselect RFKILL_SUPPORT\n";
/^legacy-sdcard$/ and $ret .= "\tselect LEGACY_SDCARD_SUPPORT\n";
/^low_mem$/ and $ret .= "\tselect LOW_MEMORY_FOOTPRINT\n";
/^small_flash$/ and $ret .= "\tselect SMALL_FLASH\n";
/^minor$/ and $ret .= "\tselect USES_MINOR\n";
/^mips16$/ and $ret .= "\tselect HAS_MIPS16\n";
/^nand$/ and $ret .= "\tselect NAND_SUPPORT\n";
/^virtio$/ and $ret .= "\tselect VIRTIO_SUPPORT\n";
/^nommu$/ and $ret .= "\tselect NOMMU\n";
/^pci$/ and $ret .= "\tselect PCI_SUPPORT\n";
/^pcie$/ and $ret .= "\tselect PCIE_SUPPORT\n";
/^pcmcia$/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
/^powerpc64$/ and $ret .= "\tselect powerpc64\n";
/^pwm$/ and $ret .= "\select PWM_SUPPORT\n";
/^ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n";
/^rfkill$/ and $ret .= "\tselect RFKILL_SUPPORT\n";
/^rootfs-part$/ and $ret .= "\tselect USES_ROOTFS_PART\n";
/^boot-part$/ and $ret .= "\tselect USES_BOOT_PART\n";
/^rtc$/ and $ret .= "\tselect RTC_SUPPORT\n";
/^separate_ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n\tselect USES_SEPARATE_INITRAMFS\n";
/^small_flash$/ and $ret .= "\tselect SMALL_FLASH\n";
/^spe_fpu$/ and $ret .= "\tselect HAS_SPE_FPU\n";
/^squashfs$/ and $ret .= "\tselect USES_SQUASHFS\n";
/^targz$/ and $ret .= "\tselect USES_TARGZ\n";
/^testing-kernel$/ and $ret .= "\tselect HAS_TESTING_KERNEL\n";
/^dt-overlay$/ and $ret .= "\tselect HAS_DT_OVERLAY_SUPPORT\n";
/^ubifs$/ and $ret .= "\tselect USES_UBIFS\n";
/^usb$/ and $ret .= "\tselect USB_SUPPORT\n";
/^usbgadget$/ and $ret .= "\tselect USB_GADGET_SUPPORT\n";
/^virtio$/ and $ret .= "\tselect VIRTIO_SUPPORT\n";
}
return $ret;
}
@ -178,7 +179,7 @@ EOF
print <<EOF;
choice
prompt "Target System"
default TARGET_x86
default TARGET_ath79
reset if !DEVEL
EOF

View File

@ -66,20 +66,22 @@ ubilayout() {
vol_id=$(( $vol_id + 1 ))
fi
case "$rootfs_type" in
"ubifs")
autoresize=1
;;
"squashfs")
# squashfs uses 1k block size, ensure we do not
# violate that
rootsize="$( round_up "$( stat -c%s "$2" )" 1024 )"
;;
esac
ubivol $vol_id rootfs "$2" "$autoresize" "$rootsize"
if [ "$2" ]; then
case "$rootfs_type" in
"ubifs")
autoresize=1
;;
"squashfs")
# squashfs uses 1k block size, ensure we do not
# violate that
rootsize="$( round_up "$( stat -c%s "$2" )" 1024 )"
;;
esac
ubivol $vol_id rootfs "$2" "$autoresize" "$rootsize"
vol_id=$(( $vol_id + 1 ))
[ "$rootfs_type" = "ubifs" ] || ubivol $vol_id rootfs_data "" 1
vol_id=$(( $vol_id + 1 ))
[ "$rootfs_type" = "ubifs" ] || ubivol $vol_id rootfs_data "" 1
fi
}
set_ubinize_seq() {
@ -101,6 +103,12 @@ while [ "$1" ]; do
shift
continue
;;
"--rootfs")
rootfs="$2"
shift
shift
continue
;;
"--part")
parts="$parts $2"
shift
@ -112,11 +120,6 @@ while [ "$1" ]; do
break
;;
*)
if [ ! "$rootfs" ]; then
rootfs=$1
shift
continue
fi
if [ ! "$outfile" ]; then
outfile=$1
shift
@ -126,12 +129,12 @@ while [ "$1" ]; do
esac
done
if [ ! -r "$rootfs" -o ! -r "$kernel" -a ! "$outfile" ]; then
echo "syntax: $0 [--uboot-env] [--part <name>=<file>] [--kernel kernelimage] rootfs out [ubinize opts]"
if [ ! -r "$rootfs" -a ! -r "$kernel" -a ! "$outfile" ]; then
echo "syntax: $0 [--uboot-env] [--part <name>=<file>] [--kernel kernelimage] [--rootfs rootfsimage] out [ubinize opts]"
exit 1
fi
ubinize="$( which ubinize )"
ubinize="$( command -v ubinize )"
if [ ! -x "$ubinize" ]; then
echo "ubinize tool not found or not usable"
exit 1

View File

@ -38,6 +38,20 @@ define Build/mt7986-gpt
rm $@.tmp
endef
define Build/gen-ubi-initramfs
sh $(TOPDIR)/scripts/ubinize-image.sh \
$(if $(UBOOTENV_IN_UBI),--uboot-env) \
--kernel $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) \
$(foreach part,$(UBINIZE_PARTS),--part $(part)) \
"$(1).tmp" \
-p $(BLOCKSIZE:%k=%KiB) -m $(PAGESIZE) \
$(if $(SUBPAGESIZE),-s $(SUBPAGESIZE)) \
$(if $(VID_HDR_OFFSET),-O $(VID_HDR_OFFSET)) \
$(UBINIZE_OPTS) && \
cat "$(1).tmp" > "$(1)" && rm "$(1).tmp" && \
$(CP) "$(1)" $(BIN_DIR)/
endef
define Device/bananapi_bpi-r3
DEVICE_VENDOR := Bananapi
DEVICE_MODEL := BPi-R3
@ -133,6 +147,9 @@ define Device/xiaomi_redmi-router-ax6000
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_IN_UBI := 1
KERNEL_INITRAMFS := kernel-bin | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | \
gen-ubi-initramfs $(KDIR)/tmp/$$(KERNEL_INITRAMFS_PREFIX)-factory.ubi
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += xiaomi_redmi-router-ax6000