diff options
author | Eric Andersen | 2000-09-20 19:22:26 +0000 |
---|---|---|
committer | Eric Andersen | 2000-09-20 19:22:26 +0000 |
commit | cff3fe3ae9696584f0c4bdad6860e8d94d5e99f9 (patch) | |
tree | 11ccadd6495c9e4fbd920896e94935551af4c14d | |
parent | 0cccdfaf363171c9f0761fbdb2028db0ea73e6b5 (diff) | |
download | busybox-cff3fe3ae9696584f0c4bdad6860e8d94d5e99f9.zip busybox-cff3fe3ae9696584f0c4bdad6860e8d94d5e99f9.tar.gz |
Added dos2unix, unix2dos, and unrpm.c thanks to robotti@metconnect.com.
-Erik
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | applets/busybox.c | 9 | ||||
-rw-r--r-- | applets/usage.c | 27 | ||||
-rw-r--r-- | busybox.c | 9 | ||||
-rw-r--r-- | busybox.def.h | 7 | ||||
-rw-r--r-- | coreutils/dos2unix.c | 45 | ||||
-rw-r--r-- | docs/busybox.pod | 47 | ||||
-rw-r--r-- | docs/busybox.sgml | 42 | ||||
-rw-r--r-- | dos2unix.c | 45 | ||||
-rw-r--r-- | internal.h | 12 | ||||
-rw-r--r-- | unix2dos.c | 49 | ||||
-rw-r--r-- | unrpm.c | 140 | ||||
-rw-r--r-- | usage.c | 27 |
13 files changed, 442 insertions, 18 deletions
@@ -20,6 +20,7 @@ * Added 'getopt' from "Alfred M. Szmidt" <ams@trillian.itslinux.org> * Fixed chmod option parsing so things like 'chmod -r /tmp/file' wouldn't work (since it thought -r was an option). Doh! + * Added dos2unix, unix2dos, and unrpm.c thanks to robotti@metconnect.com. diff --git a/applets/busybox.c b/applets/busybox.c index a7c5d37..43871b7 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -64,6 +64,9 @@ const struct BB_applet applets[] = { #ifdef BB_DMESG {"dmesg", dmesg_main, _BB_DIR_BIN, dmesg_usage}, #endif +#ifdef BB_DOS2UNIX + {"dos2unix", dos2unix_main, _BB_DIR_USR_BIN, dos2unix_usage}, +#endif #ifdef BB_DU {"du", du_main, _BB_DIR_USR_BIN, du_usage}, #endif @@ -313,6 +316,12 @@ const struct BB_applet applets[] = { #ifdef BB_UNIQ {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage}, #endif +#ifdef BB_UNIX2DOS + {"unix2dos", unix2dos_main, _BB_DIR_USR_BIN, unix2dos_usage}, +#endif +#ifdef BB_UNRPM + {"unrpm", unrpm_main, _BB_DIR_USR_BIN, unrpm_usage}, +#endif #ifdef BB_UPDATE {"update", update_main, _BB_DIR_SBIN, update_usage}, #endif diff --git a/applets/usage.c b/applets/usage.c index cee2702..4a3d734 100644 --- a/applets/usage.c +++ b/applets/usage.c @@ -207,6 +207,15 @@ const char dmesg_usage[] = ; #endif +#if defined BB_DOS2UNIX +const char dos2unix_usage[] = + "dos2unix < dosfile > unixfile\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nConverts a text file from dos format to unix format.\n" +#endif + ; +#endif + #if defined BB_DU const char du_usage[] = "du [OPTION]... [FILE]...\n" @@ -1307,6 +1316,24 @@ const char uniq_usage[] = ; #endif +#if defined BB_UNIX2DOS +const char unix2dos_usage[] = + "unix2dos < unixfile > dosfile\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nConverts a text file from unix format to dos format.\n" +#endif + ; +#endif + +#if defined BB_UNRPM +const char unrpm_usage[] = + "unrpm < package.rpm | gzip -d | cpio -idmuv\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nExtracts an rpm archive.\n" +#endif + ; +#endif + #if defined BB_UPDATE const char update_usage[] = "update [options]\n" @@ -64,6 +64,9 @@ const struct BB_applet applets[] = { #ifdef BB_DMESG {"dmesg", dmesg_main, _BB_DIR_BIN, dmesg_usage}, #endif +#ifdef BB_DOS2UNIX + {"dos2unix", dos2unix_main, _BB_DIR_USR_BIN, dos2unix_usage}, +#endif #ifdef BB_DU {"du", du_main, _BB_DIR_USR_BIN, du_usage}, #endif @@ -313,6 +316,12 @@ const struct BB_applet applets[] = { #ifdef BB_UNIQ {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage}, #endif +#ifdef BB_UNIX2DOS + {"unix2dos", unix2dos_main, _BB_DIR_USR_BIN, unix2dos_usage}, +#endif +#ifdef BB_UNRPM + {"unrpm", unrpm_main, _BB_DIR_USR_BIN, unrpm_usage}, +#endif #ifdef BB_UPDATE {"update", update_main, _BB_DIR_SBIN, update_usage}, #endif diff --git a/busybox.def.h b/busybox.def.h index c70948d..9d046ab 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -23,6 +23,7 @@ #define BB_DF #define BB_DIRNAME #define BB_DMESG +#define BB_DOS2UNIX #define BB_DUTMP #define BB_DU #define BB_DUMPKMAP @@ -98,6 +99,7 @@ #define BB_TR #define BB_TRUE_FALSE #define BB_TTY +#define BB_UNRPM #define BB_UPTIME #define BB_USLEEP #define BB_WC @@ -109,6 +111,7 @@ #define BB_UMOUNT #define BB_UNIQ #define BB_UNAME +#define BB_UNIX2DOS #define BB_UPDATE #define BB_YES // End of Applications List @@ -173,7 +176,7 @@ #define BB_FEATURE_USE_INITTAB // //Enable init being called as /linuxrc -//#define BB_FEATURE_LINUXRC +#define BB_FEATURE_LINUXRC // //Have init enable core dumping for child processes (for debugging only) //#define BB_FEATURE_INIT_COREDUMPS @@ -203,7 +206,7 @@ //#define BB_FEATURE_MOUNT_MTAB_SUPPORT // // Enable support for mounting remote NFS volumes -//#define BB_FEATURE_NFSMOUNT +#define BB_FEATURE_NFSMOUNT // // Enable support forced filesystem unmounting // (i.e. in case of an unreachable NFS system). diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c new file mode 100644 index 0000000..9634687 --- /dev/null +++ b/coreutils/dos2unix.c @@ -0,0 +1,45 @@ +/* + Mini dos2unix implementation for busybox + + Copyright 1994,1995 Patrick Volkerding, Moorhead, Minnesota USA + All rights reserved. + + Redistribution and use of this source code, with or without modification, is + permitted provided that the following condition is met: + + 1. Redistributions of this source code must retain the above copyright + notice, this condition, and the following disclaimer. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "internal.h" +#include <stdio.h> + +int dos2unix_main( int argc, char **argv ) { + int c; + if (argc > 1) { + c = *argv[1]; + if (c == '-') { + usage(dos2unix_usage); + } + } + c = getchar(); + while (c != EOF) { + /* Eat any \r's... they shouldn't be here */ + while (c == '\r') c = getchar(); + if (c == EOF) break; + putchar(c); + c = getchar(); + } + return 0; +} diff --git a/docs/busybox.pod b/docs/busybox.pod index fed8b57..5fd15ca 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod @@ -55,16 +55,17 @@ terse runtime description of their behavior. Currently defined functions include: -ar, basename, cat, chgrp, chmod, chown, chroot, chvt, clear, cp, cut, date, -dc, dd, deallocvt, df, dirname, dmesg, du, dumpkmap, dutmp, echo, false, fbset, -fdflush, find, free, freeramdisk, fsck.minix, getopt, grep, gunzip, gzip, halt, -head, hostid, hostname, id, init, insmod, kill, killall, length, ln, -loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, mkdir, -mkfifo, mkfs.minix, mknod, mkswap, mktemp, more, mount, mt, mv, nc, -nslookup, ping, poweroff, printf, ps, pwd, rdate, reboot, renice, reset, rm, rmdir, rmmod, sed, -setkeycodes, sh, sleep, sort, swapoff, swapon, sync, syslogd, tail, -tar, tee, telnet, test, touch, tr, true, tty, umount, uname, uniq, update, -uptime, usleep, uudecode, uuencode, wc, which, whoami, yes, zcat, [ +ar, basename, cat, chgrp, chmod, chown, chroot, chvt, clear, cp, cut, date, dc, +dd, deallocvt, df, dirname, dmesg, dos2unix, du, dumpkmap, dutmp, echo, false, +fbset, fdflush, find, free, freeramdisk, fsck.minix, getopt, grep, gunzip, +gzip, halt, head, hostid, hostname, id, init, insmod, kill, killall, length, +ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, mkdir, +mkfifo, mkfs.minix, mknod, mkswap, mktemp, more, mount, mt, mv, nc, nslookup, +ping, poweroff, printf, ps, pwd, rdate, reboot, renice, reset, rm, rmdir, +rmmod, sed, setkeycodes, sh, sleep, sort, swapoff, swapon, sync, syslogd, tail, +tar, tee, telnet, test, touch, tr, true, tty, umount, uname, uniq, unix2dos, +unrpm, update, uptime, usleep, uudecode, uuencode, wc, which, whoami, yes, +zcat, [ ------------------------------- @@ -412,6 +413,14 @@ Print or controls the kernel ring buffer. ------------------------------- +=item dos2unix + +Usage: dos2unix < dosfile > unixfile + +Converts a text file from dos format to unix format. + +------------------------------- + =item du Usage: du [OPTION]... [FILE]... @@ -1929,6 +1938,22 @@ Example: ------------------------------- +=item unix2dos + +Usage: unix2dos < unixfile > dosfile + +Converts a text file from unix format to dos format. + +------------------------------- + +=item unrpm + +Usage: unrpm < package.rpm | gzip -d | cpio -idmuv + +Extracts an rpm archive. + +------------------------------- + =item update Usage: update [options] @@ -2157,4 +2182,4 @@ Enrique Zanardi <ezanardi@ull.es> =cut -# $Id: busybox.pod,v 1.68 2000/09/15 17:24:13 proski Exp $ +# $Id: busybox.pod,v 1.69 2000/09/20 19:22:26 andersen Exp $ diff --git a/docs/busybox.sgml b/docs/busybox.sgml index f4161f5..e8a91fa 100644 --- a/docs/busybox.sgml +++ b/docs/busybox.sgml @@ -1,5 +1,4 @@ -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [ -]> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [ ]> <book id="BusyBoxDocumentation"> <bookinfo> <title>BusyBox - The Swiss Army Knife of Embedded Linux</title> @@ -746,6 +745,19 @@ </para> </sect1> + <sect1 id="dos2unix"> + <title>dos2unix</title> + + <para> + Usage: dos2unix < dosfile > unixfile + </para> + + <para> + Converts a text file from dos format to unix format. + </para> + + </sect1> + <sect1 id="du"> <title>du</title> @@ -3394,6 +3406,32 @@ </screen> </para> </sect1> + + <sect1 id="unix2dos"> + <title>unix2dos</title> + + <para> + Usage: unix2dos < unixfile > dosfile + </para> + + <para> + Converts a text file from unix format to dos format. + </para> + + </sect1> + + <sect1 id="unrpm"> + <titleunrpmuniq</title> + + <para> + Usage: unrpm < package.rpm | gzip -d | cpio -idmuv + </para> + + <para> + Extracts an rpm archive. + </para> + + </sect1> <sect1 id="update"> <title>update</title> diff --git a/dos2unix.c b/dos2unix.c new file mode 100644 index 0000000..9634687 --- /dev/null +++ b/dos2unix.c @@ -0,0 +1,45 @@ +/* + Mini dos2unix implementation for busybox + + Copyright 1994,1995 Patrick Volkerding, Moorhead, Minnesota USA + All rights reserved. + + Redistribution and use of this source code, with or without modification, is + permitted provided that the following condition is met: + + 1. Redistributions of this source code must retain the above copyright + notice, this condition, and the following disclaimer. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "internal.h" +#include <stdio.h> + +int dos2unix_main( int argc, char **argv ) { + int c; + if (argc > 1) { + c = *argv[1]; + if (c == '-') { + usage(dos2unix_usage); + } + } + c = getchar(); + while (c != EOF) { + /* Eat any \r's... they shouldn't be here */ + while (c == '\r') c = getchar(); + if (c == EOF) break; + putchar(c); + c = getchar(); + } + return 0; +} @@ -126,6 +126,7 @@ extern int dirname_main(int argc, char** argv); extern int deallocvt_main(int argc, char** argv); extern int df_main(int argc, char** argv); extern int dmesg_main(int argc, char** argv); +extern int dos2unix_main(int argc, char** argv); extern int du_main(int argc, char** argv); extern int dumpkmap_main(int argc, char** argv); extern int dutmp_main(int argc, char** argv); @@ -206,14 +207,16 @@ extern int true_main(int argc, char** argv); extern int tput_main(int argc, char** argv); extern int tryopen_main(int argc, char** argv); extern int tty_main(int argc, char** argv); -extern int uuencode_main(int argc, char** argv); -extern int uudecode_main(int argc, char** argv); extern int umount_main(int argc, char** argv); extern int uname_main(int argc, char** argv); -extern int uptime_main(int argc, char** argv); extern int uniq_main(int argc, char** argv); +extern int unix2dos_main(int argc, char** argv); +extern int unrpm_main(int argc, char** argv); extern int update_main(int argc, char** argv); +extern int uptime_main(int argc, char** argv); extern int usleep_main(int argc, char** argv); +extern int uuencode_main(int argc, char** argv); +extern int uudecode_main(int argc, char** argv); extern int wc_main(int argc, char** argv); extern int wget_main(int argc, char** argv); extern int which_main(int argc, char** argv); @@ -238,6 +241,7 @@ extern const char deallocvt_usage[]; extern const char df_usage[]; extern const char dirname_usage[]; extern const char dmesg_usage[]; +extern const char dos2unix_usage[]; extern const char du_usage[]; extern const char dumpkmap_usage[]; extern const char dutmp_usage[]; @@ -316,6 +320,8 @@ extern const char tty_usage[]; extern const char umount_usage[]; extern const char uname_usage[]; extern const char uniq_usage[]; +extern const char unix2dos_usage[]; +extern const char unrpm_usage[]; extern const char update_usage[]; extern const char uptime_usage[]; extern const char usleep_usage[]; diff --git a/unix2dos.c b/unix2dos.c new file mode 100644 index 0000000..c6cf81b --- /dev/null +++ b/unix2dos.c @@ -0,0 +1,49 @@ +/* + Mini unix2dos implementation for busybox + + Copyright 1994,1995 Patrick Volkerding, Moorhead, Minnesota USA + All rights reserved. + + Redistribution and use of this source code, with or without modification, is + permitted provided that the following condition is met: + + 1. Redistributions of this source code must retain the above copyright + notice, this condition, and the following disclaimer. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "internal.h" +#include <stdio.h> + +int unix2dos_main( int argc, char **argv ) { + int c; + if (argc > 1) { + c = *argv[1]; + if (c == '-') { + usage(unix2dos_usage); + } + } + c = getchar(); + while (c != EOF) { + /* Eat any \r's... they shouldn't be here */ + while (c == '\r') c = getchar(); + if (c == EOF) break; + if (c != '\n') { + putchar(c); + } else { + printf("\r\n"); + } + c = getchar(); + } + return 0; +} @@ -0,0 +1,140 @@ +/* + * Mini unrpm implementation for busybox + * + * rpmunpack.c - Utility program to unpack an RPM archive + * + * Gero Kuhlmann <gero@gkminix.han.de> 1998 + * + * This program is public domain software; you can do whatever you like + * with this source, including modifying and redistributing it. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "internal.h" +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> + +/* + * Some general definitions + */ +#define BUFSIZE 512 +#define RPM_MAGIC "\355\253\356\333" +#define GZ_MAGIC_1 '\037' +#define GZ_MAGIC_2 '\213' + +/* + * Global variables + */ +static char buffer[BUFSIZE]; +static char *progname; +static int infile, outfile; + +/* + * Read a specified number of bytes from input file + */ +static void myread(int num) +{ + int err; + + if ((err = read(infile, buffer, num)) != num) { + if (err < 0) + perror(progname); + else + fprintf(stderr, "unexpected end of input file\n"); + exit(1); + } +} + +/* + * Main program + */ +int unrpm_main(int argc, char **argv) +{ + int len, status = 0; + + /* Get our own program name */ + if ((progname = strrchr(argv[0], '/')) == NULL) + progname = argv[0]; + else + progname++; + + /* Check for command line parameters */ + if (argc>=2 && *argv[1]=='-') { + usage(unrpm_usage); + } + + /* Open input file */ + if (argc == 1) + infile = STDIN_FILENO; + else if ((infile = open(argv[1], O_RDONLY)) < 0) { + perror(progname); + exit(1); + } + + /* Read magic ID and output filename */ + myread(4); + if (strncmp(buffer, RPM_MAGIC, 4)) { + fprintf(stderr, "input file is not in RPM format\n"); + exit(1); + } + myread(6); /* Skip flags */ + myread(64); + buffer[64] = '\0'; + + /* Open output file */ + strcat(buffer, ".cpio.gz"); + if (infile == STDIN_FILENO) + outfile = STDOUT_FILENO; + else if ((outfile = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) { + perror(progname); + exit(1); + } + + /* + * Now search for the GZIP signature. This is rather awkward, but I don't + * know any other way how to find out the exact starting position of the + * archive within the input file. There are a couple of data structures + * and texts (obviously descriptions, installation shell scripts etc.) + * coming before the archive, but even they start at different offsets + * with different RPM files. However, it looks like the GZIP signature + * never appears before offset 0x200, so we skip these first couple of + * bytes to make the signature scan a little more reliable. + */ + myread(0x200 - 74); + while (status < 2) { + myread(1); + if (status == 0 && buffer[0] == GZ_MAGIC_1) + status++; + else if (status == 1 && buffer[0] == GZ_MAGIC_2) + status++; + else + status = 0; + } + buffer[0] = GZ_MAGIC_1; + buffer[1] = GZ_MAGIC_2; + if (write(outfile, buffer, 2) < 0) { + perror(progname); + exit(1); + } + + /* Now simply copy the GZIP archive into the output file */ + while ((len = read(infile, buffer, BUFSIZE)) > 0) { + if (write(outfile, buffer, len) < 0) { + perror(progname); + exit(1); + } + } + if (len < 0) { + perror(progname); + exit(1); + } + close(outfile); + close(infile); + exit(0); +} @@ -207,6 +207,15 @@ const char dmesg_usage[] = ; #endif +#if defined BB_DOS2UNIX +const char dos2unix_usage[] = + "dos2unix < dosfile > unixfile\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nConverts a text file from dos format to unix format.\n" +#endif + ; +#endif + #if defined BB_DU const char du_usage[] = "du [OPTION]... [FILE]...\n" @@ -1307,6 +1316,24 @@ const char uniq_usage[] = ; #endif +#if defined BB_UNIX2DOS +const char unix2dos_usage[] = + "unix2dos < unixfile > dosfile\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nConverts a text file from unix format to dos format.\n" +#endif + ; +#endif + +#if defined BB_UNRPM +const char unrpm_usage[] = + "unrpm < package.rpm | gzip -d | cpio -idmuv\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nExtracts an rpm archive.\n" +#endif + ; +#endif + #if defined BB_UPDATE const char update_usage[] = "update [options]\n" |