read and write scsi devices file from linux , like sdb,sdc - c

I want to write my own tag on the device file (scsi file sdb, sdc...) on Linux.
I use linux C open(), read(), write() functions on /dev/sdb file, write my key in this file. But when usb disk device Unplug from computer and plug again, in /dev/sdb's key, sometimes it's gone, or is unstable.
I don't know why.
char readBuf[512] = { 0 };
char key[12] = "h%27dcd*()jd";
int fd = open("/dev/sdb",O_RDWR);
lseek(fd,1024,SEEK_SET);
read(fd,readBuf,512);
for(int i=0; i<sizeof key; ++i)
{
readBuf[i] = ~key[i];
}
lseek(fd,1024,SEEK_SET);
write(fd,readBuf,512);
//In order to mark the Usb disk bear fruit...

for setting a fixed mount point:
you can assign a static mount point (like /dev/sdb) for USB devices using udev rules and a symlink. you can identify the device in the udev rule by i.e. vendor id and product id,...
ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_device"
https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name
for writing bit-wise to specific memory location on the stick:
to write data bytewise to arbitrary blocks on a block device use tools like dd ( https://en.wikipedia.org/wiki/Dd_(Unix) ). file io tools like read(), write() can not be used for writing bytewise WITHOUT using a file...

Related

posix_spawn pipe dmesg to python script

I've got several USB to 422 adapters in my test system. I've used FTProg to give each adapter a specific name: Sensor1, Sensor2, etc. They will all be plugged in at power on. I don't want to hard code each adapter to a specific ttyUSBx. I want the drivers to figure out which tty it needs to use. I'm developing in C for a linux system. My first thought was to something like this in my startup code.
system("dmesg | find_usb.py");
The python script would find the devices since each one has a unique Product Description. Then using the usb tree to associate each device with its ttyUSBx. The script would then create /tmp/USBDevs which would just be a simple device:tty pairing that would be easy for the C code to search.
I've been told...DoN't UsE sYsTeM...use posix_spawn(). But I'm having problems getting the output of dmesg piped to my python script. This isn't working
char *my_args[] = {"dmesg", "|", "find_usb.py", NULL};
pid_t pid;
int status;
status = posix_spawn(&pid, "/bin/dmesg", NULL, NULL, my_args, NULL);
if(status == 0){
if(waitpid(pid, &status, 0) != -1);{
printf("posix_spawn exited: %i", status);
}
I've been trying to figure out how to do this with posix_spawn_file_actions(), but I'm not allowed to hit the peak of the 'Ballmer Curve' at work.
Thanks in advance
Instead of using /dev/ttyUSB* devices, write udev rules to generate named symlinks to the devices. For a brief how-to, see here. Basically, you'll have an udev rule for each device, ending with say SYMLINK+=Sensor-name, and in your program, use /dev/Sensor-name for each sensor. (I do recommend using Sensor- prefix, noting the initial Capital letter, as all device names are currently lowercase. This avoids any clashes with existing devices.)
These symlinks will then only exist when the matching device is plugged in, and will point to the correct device (/dev/ttyUSB* in this case). When the device is removed, udev automagically deletes the symlink also. Just make sure your udev rule identifies the device precisely (not just vendor:device, but serial number also). I'd expect the rule to look something like
SUBSYSTEM=="tty", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", ATTRS{serial}=="SSSSSSSS", SYMLINK+="Sensor-name"
where VVVV is the USB Vendor ID (four hexadecimal digits), PPPP is the USB Product ID (four hexadecimal digits), and SSSSSSSS is the serial number string. You can see these values using e.g. udevadm info -a -n /dev/ttyUSB* when the device is plugged in.
If you still insist on parsing dmesg output, using your own script is a good idea.
You could use FILE *handle = popen("dmesg | find_usb.py", "r"); and read from handle like it was a file. When complete, close the handle using int exitstatus = pclose(handle);. See man popen and man pclose for the details, and man 2 wait for the WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG() macros you'll need to use to examine exitstatus (although in your case, I suppose you can just ignore any errors).
If you do want to use posix_spawn() (or roughly equivalently, fork() and execvp()), you'd need to set up at least one pipe (to read the output of the spawned command) – two if you spawn/fork+exec both dmesg and your Python script –, and that gets a bit more complicated. See man pipe for details on that. Personally, I would rewrite the Python script so that it executes dmesg itself internally, and only outputs the device name(s). With posix_spawn(), you'd init a posix_file_actions_t, with three actions: _adddup2() to duplicate the write end of the pipe to STDOUT_FILENO, and two _addclose()s to close both ends of the pipe. However, I myself prefer to use fork() and exec() instead, somewhat similar to the example by Glärbo in this answer.

to keep files after kernel rebooting

i need to use reboot() system call (to reboot the kernel 2.6.29 with ARM) and i tried the code below:
#include <stdio.h>
#include <linux/reboot.h>
#include <unistd.h>
int main()
{
reboot(LINUX_REBOOT_CMD_RESTART);
}
it works well! but what im wondering is after rebooting the kernel im loosing the files being saved.
i mean if use this code, "url" file is not saved after reboot.
int main()
{
FILE *pFile = fopen("url", "a"); // for .txt file
// write to file/read from file ... etc
fclose(pFile);
int fdUART = open("/dev/ttySAC0", O_RDWR | O_NOCTTY | O_NDELAY);
// some operations on UART port
close(fdUART);
/* Ethernet raw package process*/
/* Char dev driver open and communicate with FPGA fifo */
/* so on */
reboot(LINUX_REBOOT_CMD_RESTART);
}
and am using the UART, Ethernet, char drivers and just would like to know reboot() call systems's effect to my system.
any help highly appreciated thanks.
You've written in the comments that the file system is cramfs.
From the Wikipedia page for cramfs:
The compressed ROM file system (or cramfs) is a free (GPL'ed) read-only Linux file system designed for simplicity and space-efficiency. It is mainly used in embedded systems and small-footprint systems.
Note that it's read-only: that means your changes won't be preserved.
You'll need to write to persistent storage to have your changes preserved.

Finding the description of the device connected to /dev/input/eventX

I have a program that is listening to a certain event file handle. Is there a file I can read to get details about the specific event's device that I am listening to?
Assuming that (a) you're on Linux and (b) you have sysfs mounted (typically on /sys), you can look at /sys/class/input/eventX. This will be a symlink into the device tree; this should provide you some device details. For example:
$ readlink /sys/class/input/event4
../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.1/input/input4/event4
For USB devices, you could then probably mount a usbfs filesystem and check out the devices file for more information.
Do you have access to the file descriptor or is this an external program? If this is your fd to the actual device, a list of ioctls provides you with most info you'll need. Have a look at print_device_info from evtest, it does exactly that:
http://cgit.freedesktop.org/evtest/tree/evtest.c#n753

Creating a pcap file

I need to save UDP packets to a file and would like to use the pcap format to reuse the various tools available (wireshark, tcpdump, ...).
There are some information in this thread but I can't find how to write the global file header 'struct pcap_file_header'.
pcap_t* pd = pcap_open_dead(DLT_RAW, 65535);
pcap_dumper_t* pdumper = pcap_dump_open(pd, filename);
struct pcap_file_header file_hdr;
file_hdr.magic_number = 0xa1b2c3d4;
file_hdr.version_major = 2;
file_hdr.version_minor = 4;
file_hdr.thiszone = 0;
file_hdr.sigfigs = 0;
file_hdr.snaplen = 65535;
file_hdr.linktype = 1;
// How do I write file_hdr to m_pdumper?
while( (len = recvmsg(sd, &msg_hdr, 0)) > 0 )
pcap_dump((u_char*)m_pdumper, &m_pcap_pkthdr, (const u_char*)&data);
How should I write the global file header?
If there is no specific pcap function available, how can I retrieve the file descriptor to insert the header using write()?
You shouldn't need to write that header, pcap_open_dead should do it for you. You only need to fill out and write that header yourself if you want to write the file directly instead of using pcap_dump and friends. There's an example here of a trivial program write out a pcap file with those functions.
original answer, concerning writing the file directly:
I can't remember exactly how this works, but I wrote a patch to redir a while ago that would write out pcap files, you may be able to use it as an example.
You can find it attached to this debian bug. (bug link fixed.)
Some of it is for faking the ethernet and IP headers, and may not be applicable as you're using pcap_dump_open and pcap_dump where as the patch linked above writes out the pcap file without using any libraries, but I'll leave this here anyway in case it helps.
If you are interested in UDP and TCP only, you should use DLT_EN10MB instead of DLT_RAW ( cf pcap_open_dead to simulate full UDP packets capture ).
It is much better when editing in WireShak.

How do I find the size of mounted USB flash drive in C?

I have a flash drive device (/dev/sda1) mounted to /mnt on an embedded linux system (kernel 2.6.23). Using C how do I work out the size of the drive?
On Linux, if you're not worried about portability (C doesn't know about drives, so any such specific code will be unportable), use statfs():
struct statfs fsb;
if(statfs("/mnt", &fsb) == 0)
printf("device has %ld blocks, each %ld bytes\n", fsb.f_blocks, fsb.f_bsize);
Read and parse a number in device's sysfs entry. In your case,
Full device (all partitions and partition table): /sys/block/sda/size
Logical partition on this device: /sys/block/sda/sda1/size
The device does not have to be mounted yet.
If you have no problem using external tools, exec this :
df -h | grep -i /dev/sda1
using popen, and parse the resulting line with strtok.

Resources