Aligning columns in ls - c

i'm writing an implementation of ls command but i found a problem with
the columns, i want to align them like the real ls -l
drwx------# 3 haxor123 candidate 102 Oct 3 14:43 Applications
drwxr-xr-x 21 haxor123 candidate 714 Nov 29 21:07 Desktop
drwxr-xr-x 4 haxor123 candidate 136 Nov 6 19:54 Documents
drwx------ 9 haxor123 candidate 306 Nov 28 22:28 Downloads
drwxr-xr-x# 396 haxor123 candidate 13464 Nov 29 19:52 Library
drwx------+ 3 haxor123 candidate 102 Aug 9 16:38 Movies
drwx------+ 4 haxor123 candidate 136 Oct 5 14:13 Music
drwxr-xr-x 3 haxor123 candidate 102 Oct 4 23:23 PicineRe
drwxr-xr-x 4 haxor123 candidate 136 Oct 4 23:52 PicineRee
drwxr-xr-x 3 haxor123 candidate 102 Oct 4 22:32 PicineReloaded
drwx------+ 4 haxor123 candidate 136 Nov 11 16:46 Pictures
drwxr-xr-x 6 haxor123 candidate 204 Nov 12 21:38 exam-basedir
lrwxr-xr-x 1 haxor123 candidate 34 Jul 16 10:12 goinfre ->
/Volumes/Storage/goinfre/haxor123/
drwxr-xr-x 4 haxor123 candidate 136 Oct 3 15:14 s
That's a part from ls -l function
temp = list;
ft_putstr("total ");
printblocks(list);
ft_putchar('\n');
while (temp != NULL)
{
lstat(temp->full_path, &fstat);
ft_permissions(temp, fstat);
ft_putstr(" ");
bytes1 = ft_itoa(fstat.st_nlink);
ft_putstr(bytes1);
ft_putstr(get_user(fstat));
bytes = ft_itoa(fstat.st_size);
len = ft_strlen(bytes);
ft_putstr(ft_strjoin(bytes, " "));
get_time(fstat, temp);
temp = temp->next;
if (temp != NULL)
ft_putchar('\n');

If you would like to read the source code for GNU commands directly, you can do so...and it may be a good learning experience:
Where can I find source code for Linux core commands?
In particular, here is ls.c:
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c
The only way to know precisely "how ls does it" comes from that file. We are not psychic (at least I am not) so if you're going to be asking about any other programming method, it needs to be self-contained in your question what you're specifically trying to achieve and why you can't achieve it.

Related

How to change from NTFS to "noramal FS" in USB memory?

Several years ago, I change my usb file system(FS) from default FS to NTFS. but now, I want to change to default FS.
What is the way to change that FS?
Machine Enviroment: macOSX 10.14
default Format: MS-DOS(FAT32)
current Format: Windows NT FileSystem(NTFS)
USB internal file by terminal
>>ls -l -FG -a
total 6403240
-rwxr-xr-x# 1 takezakiyuuta staff 2352 8 2 2018 $UGM*
drwxr-xr-x 1 takezakiyuuta staff 8192 8 23 2018 ./
drwxr-xr-x+ 10 root wheel 320 2 21 19:39 ../
-rwxr-xr-x 1 takezakiyuuta staff 12 8 9 2018 .avm_speed_test2*
drwxr-xr-x 1 takezakiyuuta staff 0 8 10 2018 .fseventsd/
-rwxr-xr-x 1 takezakiyuuta staff 11 8 23 2018 .hd_keepalive*
drwxr-xr-x 1 takezakiyuuta staff 16384 8 23 2018 .index/
drwxr-xr-x 1 takezakiyuuta staff 16384 8 23 2018 .thumb/
-rwxr-xr-x 1 takezakiyuuta staff 354368793 8 18 2018 180818-1039.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 156281700 8 18 2018 180818-1042.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 232452505 8 18 2018 180818-1044.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 164182010 8 20 2018 180820-1817.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 470749844 8 20 2018 180820-1820.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 299472449 8 20 2018 180820-1824.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 112263523 8 23 2018 180823-2044.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 56539836 8 23 2018 180823-2046.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 42780723 8 23 2018 180823-2048.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 290799372 8 23 2018 180823-2050.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 365304821 8 23 2018 180823-2052.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 396741824 8 23 2018 180823-2055.mp4*
-rwxr-xr-x 1 takezakiyuuta staff 336483041 8 23 2018 180823-2058.mp4*
drwxr-xr-x# 1 takezakiyuuta staff 0 8 2 2018 System Volume Information/

/usr/bin/ld: cannot find -lruby

I hope build ruby c extension with cmake, but I get /usr/bin/ld: cannot find -llibruby in console, here is my code:
CMakeLists.txt
cmake_minimum_required(VERSION 3.3)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
file(GLOB cs *.c)
include_directories($ENV{HOME}/.rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux
$ENV{HOME}/.rbenv/versions/2.2.3/include/ruby-2.2.0)
foreach (c ${cs})
get_filename_component(exe ${c} NAME_WE)
add_executable(${exe} ${cs})
endforeach ()
add_library(mytest SHARED MyTest.c)
link_directories($ENV{HOME}/.rbenv/versions/2.2.3/lib)
find_library(ruby NAMES ruby)
target_link_libraries(mytest ruby)
and here is ruby lib:
roroco#roroco-Zhaoyang-K49 ~/Dropbox/rbs/ro_plans $ lsa ~/.rbenv/versions/2.2.3/lib
total 61424
drwxr-xr-x 4 roroco roroco 4096 Nov 21 23:49 .
drwxr-xr-x 6 roroco roroco 4096 Oct 13 22:10 ..
lrwxrwxrwx 1 roroco roroco 16 Nov 21 23:49 libruby.so -> libruby.so.2.2.0
lrwxrwxrwx 1 roroco roroco 16 Nov 21 23:49 libruby.so.2.2 -> libruby.so.2.2.0
-rwxr-xr-x 1 roroco roroco 13573794 Nov 21 23:49 libruby.so.2.2.0
-rw-r--r-- 1 roroco roroco 49306632 Nov 21 23:47 libruby-static.a
drwxr-xr-x 2 roroco roroco 4096 Nov 21 23:49 pkgconfig
drwxr-xr-x 6 roroco roroco 4096 Oct 13 22:10 ruby

prints out wrongly,positions of characters mixed up, whats wrong,loop

Mycode prints many lines with 9 elements each. If the line (first element) starts with 'd', then do not print out the rest elements of the line. so if you try ls -l | mycode it will delete lines starting with 'd'. BUT for some reasons the elements move left by one if for example:
ls -l
drwxrwxrwx 2 alk lotus 35 Sep 23 19.00 directory1
-rwxrwxrwx 2 alk lotus 345 Sep 23 13.00 file1
drwxrwxrwx 3 alk lotus 245 Sep 23 19.20 directory2
drwxrwxrwx 24 alk lotus 15 Sep 23 12.00 directory3
-rwxrwxrwx 5 alk lotus 25 Sep 23 14.00 file2
-rwxrwxrwx 8 alk lotus 25 Sep 23 10.00 file3
ls -l | mycode
-rwxrwxrwx 2 alk lotus 345 Sep 23 13.00
file1 -rwxrwxrwx 5 alk lotus 25 Sep
23 14.00 file2 -rwxrwxrwx 8 alk lotus 25 Sep
23 10.00 file3
So why file2 file1 goes down? I wanna that file to stay in his place....After that all positions are mixed up there....Help please to fix this...
my code here:
The logic in your code seems not correct. What you want to do is to remove lines that starts with d, however in the code you it does something else.
I'm presenting you an example which is expected to work, which shall replace your code example:
while (fgets(string, 1024, stdin))
if (string[0] != 'd')
printf("%s", string); // don't use puts cuz fgets would store the newline
I don't understand why you aren't just using only fgets:
for (i=0; i<9;i++){
if (NULL != fgets(string,1024,stdin)) {
if (string[0] != 'd'){
printf("%s\n", string);
}
}
else break;
}

Unix `find` command that returns path and whether or not it's a file/directory?

When you do ls -la it returns each path along with info of whether or not it's a file/directory:
$ ls -la
drwxr-xr-x 11 viatropos staff 374 Jan 21 21:24 .
drwxr-xr-x 41 viatropos staff 1394 Feb 2 00:48 ..
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .gitignore
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .npmignore
-rw-r--r-- 1 viatropos staff 647 Jan 21 21:23 README.md
-rw-r--r-- 1 viatropos staff 3069 Feb 5 20:17 index.js
drwxr-xr-x 8 viatropos staff 272 Feb 5 20:06 node_modules
-rw-r--r-- 1 viatropos staff 291 Jan 21 21:24 package.json
drwxr-xr-x 4 viatropos staff 136 Jan 21 21:23 test
Is there a way to do this using the find command (and glob * functionality)? So, finding all paths within node_modules and having it return the path and whether or not it's a file directory? Something like:
$ find node_modules -name 'lib/*'
d node_modules/express/lib/
f node_modules/express/lib/index.js
...
How about find ... -printf '%y %p\n'? (This is probably a GNU find extension, though.)
Try this script, I called it "findfl". The "mtime" clause finds files changed in the last 3 days.
Directories will have "/" appended.
#!/bin/sh
# find files produced recently, matching input pattern
[ $1 ] || { echo "Usage: findfl <file-name-pattern>" ; exit ; }
TOPDIR=/home/usr/fred #the directory you want to search
echo "Searching $TOPDIR"
find . -mtime -3 -name *$1* 2>/dev/null | xargs -n 99 ls -lptr | sed "s! ./! $TOPDIR/!g"

How to map /proc/bus/usb/devices entry to a /dev/sdX device?

I need to know how I can figure out to which entry in /proc/bus/usb/devices a /dev/sdX device maps to. Basically, I need to know the vendor id and product id of a given USB stick (which may not have a serial number).
In my case, I have this entry for my flash drive in /proc/bus/usb/devices:
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0781 ProdID=5530 Rev= 2.00
S: Manufacturer=SanDisk
S: Product=Cruzer
S: SerialNumber=0765400A1BD05BEE
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=200mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I happen to know that in my case it is /dev/sda, but I'm not sure how I can figure this out in code. My first approach was to loop through all /dev/sdXX devices and issue a SCSI_IOCTL_GET_BUS_NUMBER and/or SCSI_IOCTL_GET_IDLUN request, but the information returned doesn't help me match it up:
/tmp # ./getscsiinfo /dev/sda
SCSI bus number: 8
ID: 00
LUN: 00
Channel: 00
Host#: 08
four_in_one: 08000000
host_unique_id: 0
I'm not sure how I can use the SCSI bus number or the ID, LUN, Channel, Host to map it to the entry in /proc/bus/usb/devices. Or how I could get the SCSI bus number from the /proc/bus/usb/001/006 device, which is a usbfs device and doesn't appear to like the same ioctl's:
/tmp # ./getscsiinfo /proc/bus/usb/001/006
Could not get bus number: Inappropriate ioctl for device
Here's the test code for my little getscsiinfo test tool:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <sys/ioctl.h>
struct scsi_idlun
{
int four_in_one;
int host_unique_id;
};
int main(int argc, char** argv) {
if (argc != 2)
return 1;
int fd = open(argv[1], O_RDONLY | O_NONBLOCK);
if (fd < 0)
{
printf("Error opening device: %m\n");
return 1;
}
int busNumber = -1;
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &busNumber) < 0)
{
printf("Could not get bus number: %m\n");
close(fd);
return 1;
}
printf("SCSI bus number: %d\n", busNumber);
struct scsi_idlun argid;
if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &argid) < 0)
{
printf("Could not get id: %m\n");
close(fd);
return 1;
}
printf("ID: %02x\n", argid.four_in_one & 0xFF);
printf("LUN: %02x\n", (argid.four_in_one >> 8) & 0xFF);
printf("Channel: %02x\n", (argid.four_in_one >> 16) & 0xFF);
printf("Host#: %02x\n", (argid.four_in_one >> 24) & 0xFF);
printf("four_in_one: %08x\n", (unsigned int)argid.four_in_one);
printf("host_unique_id: %d\n", argid.host_unique_id);
close(fd);
return 0;
}
Does anyone have any idea?
udevadm is capable of what your are trying to achieve.
udevadm info -a -p $(udevadm info -q path -n /dev/sda)
udevadm's sources will tell you how it is done.
I believe you can collect such information using libudev library.
Here are some details about it: http://www.signal11.us/oss/udev/
I found something like this on above site:
.. Using libudev, we'll be able to inspect the devices, including their Vendor ID (VID), Product ID (PID), serial number, and device strings, without ever opening the device. Further, libudev will tell us exactly where inside /dev the device's node is located, giving the application a robust and distribution-independent way of accessing the device. ...
This isn't all that easy, nor very well documented (at least from a high-level perspective). The following should work in Kernel's from version 3.1 upward (at least).
I have found the easiest (probably not the only way) is to navigate from the block device entry and test each block device until you find the one that matches your USB entry.
For example, given a block device in /sys/block, such as sdb, you can find the hardware device descriptor entry like this:
# cd /sys/block
# cd $(readlink sdb); cd ../../../../../..
# ls -l
total 0
drwxr-xr-x 6 root root 0 Aug 14 10:47 1-1:1.0
-rw-r--r-- 1 root root 4096 Aug 14 10:52 authorized
-rw-r--r-- 1 root root 4096 Aug 14 10:52 avoid_reset_quirk
-r--r--r-- 1 root root 4096 Aug 14 10:47 bcdDevice
-rw-r--r-- 1 root root 4096 Aug 14 10:49 bConfigurationValue
-r--r--r-- 1 root root 4096 Aug 14 10:47 bDeviceClass
-r--r--r-- 1 root root 4096 Aug 14 10:49 bDeviceProtocol
-r--r--r-- 1 root root 4096 Aug 14 10:49 bDeviceSubClass
-r--r--r-- 1 root root 4096 Aug 14 10:49 bmAttributes
-r--r--r-- 1 root root 4096 Aug 14 10:49 bMaxPacketSize0
-r--r--r-- 1 root root 4096 Aug 14 10:49 bMaxPower
-r--r--r-- 1 root root 4096 Aug 14 10:49 bNumConfigurations
-r--r--r-- 1 root root 4096 Aug 14 10:49 bNumInterfaces
-r--r--r-- 1 root root 4096 Aug 14 10:49 busnum
-r--r--r-- 1 root root 4096 Aug 14 10:52 configuration
-r--r--r-- 1 root root 65553 Aug 14 10:47 descriptors
-r--r--r-- 1 root root 4096 Aug 14 10:52 dev
-r--r--r-- 1 root root 4096 Aug 14 10:49 devnum
-r--r--r-- 1 root root 4096 Aug 14 10:52 devpath
lrwxrwxrwx 1 root root 0 Aug 14 10:47 driver -> ../../../../../../bus/usb/drivers/usb
drwxr-xr-x 3 root root 0 Aug 14 10:52 ep_00
-r--r--r-- 1 root root 4096 Aug 14 10:47 idProduct
-r--r--r-- 1 root root 4096 Aug 14 10:47 idVendor
-r--r--r-- 1 root root 4096 Aug 14 10:52 ltm_capable
-r--r--r-- 1 root root 4096 Aug 14 10:47 manufacturer
-r--r--r-- 1 root root 4096 Aug 14 10:49 maxchild
lrwxrwxrwx 1 root root 0 Aug 14 10:52 port -> ../1-0:1.0/port1
drwxr-xr-x 2 root root 0 Aug 14 10:52 power
-r--r--r-- 1 root root 4096 Aug 14 10:47 product
-r--r--r-- 1 root root 4096 Aug 14 10:52 quirks
-r--r--r-- 1 root root 4096 Aug 14 10:47 removable
--w------- 1 root root 4096 Aug 14 10:52 remove
-r--r--r-- 1 root root 4096 Aug 14 10:47 serial
-r--r--r-- 1 root root 4096 Aug 14 10:49 speed
lrwxrwxrwx 1 root root 0 Aug 14 10:47 subsystem -> ../../../../../../bus/usb
-rw-r--r-- 1 root root 4096 Aug 14 10:47 uevent
-r--r--r-- 1 root root 4096 Aug 14 10:52 urbnum
-r--r--r-- 1 root root 4096 Aug 14 10:49 version
(You can find excellent documentation for the contents of the USB Descriptor here on the BeyondLogic site.)
Given the above, you should be able to map one or more of the USB device fields to the contents of /proc/bus/usb/devices. I find that the serial number is the easiest to match on, so that if you were to cat serial above, you would get the same serial number as listed:
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0781 ProdID=5575 Rev=01.26
S: Manufacturer=SanDisk
S: Product=Cruzer Glide
S: SerialNumber=4C530100801115115112
C: #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=200mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
If you go to /sys/block, you can list the full path to the host device entry in the storage driver sysfs entry for each device. Typically, I do this using some programmatic means instead of at the shell prompt, but here you can see the links themselves:
# ls -l sd*
lrwxrwxrwx 1 root root 0 Aug 14 10:45 sda -> ../devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 Aug 14 10:47 sdb -> ../devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/host33/target33:0:0/33:0:0:0/block/sdb
Note that you mustn't make any assumptions about the numbers you see in the links. Depending upon the bus subsystem, the mappings could be quite different. For example, on a Raspberry Pi, it looks like this:
# ls -l sd*
lrwxrwxrwx 1 root root 0 Aug 13 23:54 sda -> ../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host3/target3:0:0/3:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 Aug 13 23:54 sdb -> ../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/host4/target4:0:0/4:0:0:0/block/sdb
So, the best approach is to take the approach listed at the top and navigate relative to the storage driver to find the USB device descriptor.
I'd be curious about more authoritative answers to this. The method above was arrived at by trial-and-error but has been working on several different devices and Kernels with no problem.
Instead of using proc/bus/usb which is for usbfs you can use /proc/scsi/scsi. In there you can find the Vendor and Serial number with specific channel ID and LUN number.

Resources