Определение катры разбивка и монтироваие
Бабай
Регистрация: 28.05.2009
Пол: Мужчина
Из: Екатеринбург
Есть следущая задача
Устройсво скидывает на карточку(ММС или SD) данные
Но при включении карта должна определиться и если на на ней не фат то отформатироваться
С этим проьлем нет - решил эту задачу
А вот если карта вообще чистая - нет на ней еще разделов
тут я пока в тупике
Прошу помочь
Заранее спасибо
вот что получилось
Код
#include <stdio.h>
#include <errno.h>
#include <mntent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <sys/fcntl.h>
#include <wait.h>
#define AFFS_SUPER_MAGIC 0xADFF
#define EFS_SUPER_MAGIC 0x00414A53
#define EXT_SUPER_MAGIC 0x137D
#define EXT2_OLD_SUPER_MAGIC 0xEF51
#define EXT2_SUPER_MAGIC 0xEF53
#define HPFS_SUPER_MAGIC 0xF995E849
#define ISOFS_SUPER_MAGIC 0x9660
#define MINIX_SUPER_MAGIC 0x137F
#define MINIX_SUPER_MAGIC2 0x138F
#define MINIX2_SUPER_MAGIC 0x2468
#define MINIX2_SUPER_MAGIC2 0x2478
#define MSDOS_SUPER_MAGIC 0x4d44
#define NCP_SUPER_MAGIC 0x564c
#define NFS_SUPER_MAGIC 0x6969
#define PROC_SUPER_MAGIC 0x9fa0
#define SMB_SUPER_MAGIC 0x517B
#define XENIX_SUPER_MAGIC 0x012FF7B4
#define SYSV4_SUPER_MAGIC 0x012FF7B5
#define SYSV2_SUPER_MAGIC 0x012FF7B6
#define COH_SUPER_MAGIC 0x012FF7B7
#define UFS_SUPER_MAGIC 0x00011954
#define XFS_SUPER_MAGIC 0x58465342
#define _XIAFS_SUPER_MAGIC 0x012FD16D
void process(const char *filename);
void do_statfs(const struct mntent *fs);
int errors = 0;
char *myname;
long card_ftype;
/* */
int main(int argc, char **argv)
{
int c;
char *file = "/etc/mtab";
char * ls_args[]={
"ls",
"-la",
"/dev/sdd1",
NULL
};
char * dd_args[]={
"dd",
"if=/dev/zero",
"of=/dev/partition",
"bs=1k",
"count=100000",
NULL
};
char * mkfs_args[]={
"mkfs.vfat",
"/dev/partition",
NULL
};
char * dd_args1[]={
"dd",
"if=/dev/partition",
"of=/dev/sdd",
NULL
};
char * mount_args[]={
NULL
};
pid_t status, childpid;
int exit_status;
myname = argv[0];
while((c=getopt(argc,argv, "f:"))!=-1)
{
switch(c)
{
case 'f':
file = optarg;
break;
default:
exit(1);
}
}
process(file);
/*
*/
int fd = open("/dev/sdd", O_RDWR);
if(fd==-1)
{
perror("open");
printf("Insert card and restart device.\n");
return 1;
}
else
{
printf("SD Card detect.\n");
// определяем наличие ФС
if(card_ftype != MSDOS_SUPER_MAGIC)
{
// форматируем карточку
printf("....\n");
status = fork();
if(status == -1)
{
fprintf(stderr,"Fork error\n");
return 1;
}
// Порождаем дочерний процесс
if(status == 0)
{
printf("execute : %s %s %s %s %s\n",dd_args[0],dd_args[1],dd_args[2],dd_args[3],dd_args[4]);
execvp("dd", dd_args);
fprintf(stderr,"Exec error\n");
return 1;
}
// Patern
childpid = wait(&exit_status);
if(WIFEXITED (exit_status))
{
printf("Process with PID=%d " "has existed with code=%d\n", childpid, WEXITSTATUS(exit_status));
} //
status = fork();
if(status == -1)
{
fprintf(stderr,"Fork error\n");
return 1;
}
// Порождаем дочерний процесс
if(status == 0)
{
printf("execute: %s %s\n", mkfs_args[0], mkfs_args[1]);
execvp("mkfs.vfat", mkfs_args);
fprintf(stderr,"Exec error\n");
return 1;
}
// Patern
childpid = wait(&exit_status);
if(WIFEXITED (exit_status))
{
printf("Process with PID=%d " "has existed with code=%d\n", childpid, WEXITSTATUS(exit_status));
} //
status = fork();
if(status == -1)
{
fprintf(stderr,"Fork error\n");
return 1;
}
// Порождаем дочерний процесс
if(status == 0)
{
printf("execute: %s %s %s\n", dd_args1[0], dd_args1[1], dd_args1[2]);
execvp("dd", dd_args1);
fprintf(stderr,"Exec error\n");
return 1;
}
// Patern
childpid = wait(&exit_status);
if(WIFEXITED (exit_status))
{
printf("Process with PID=%d " "has existed with code=%d\n", childpid, WEXITSTATUS(exit_status));
} //
}
else
{
// карточка отфарматирована
printf("Filesystem type: %d\n",card_ftype);
execve("/bin/ls", ls_args, environ);
}
}
return (errors != 0);
}
/* */
void process(const char *filename)
{
FILE *fp;
struct mntent *fs;
fp = setmntent(filename, "r");
/* if(fp==NULL)
{
fprintf(stderr, "%s: %s: could not open: %s\n",myname,filename,stderr(errno));
exit(1);
} */
while((fs = getmntent(fp)) != NULL)
do_statfs(fs);
endmntent(fp);
}
/* type2str --- преобразование тира fs в строку statfs(2)*/
const char *type2str(long type)
{
static struct fsname
{
long type;
const char *name;
} table[] = {
{AFFS_SUPER_MAGIC, "AFFS"},
{COH_SUPER_MAGIC, "COH"},
{EXT2_OLD_SUPER_MAGIC, "EXT2_OLD"},
{EXT2_SUPER_MAGIC, "EXT2"},
{HPFS_SUPER_MAGIC, "HPFS"},
{ISOFS_SUPER_MAGIC, "ISOFS"},
{MINIX2_SUPER_MAGIC, "MINIX V2"},
{MINIX2_SUPER_MAGIC2, "MINIX V2 30 char"},
{MINIX_SUPER_MAGIC, "MINIX"},
{MINIX_SUPER_MAGIC2, "MINIX 30 char"},
{MSDOS_SUPER_MAGIC, "MSDOS"},
{NCP_SUPER_MAGIC, "NCP"},
{NFS_SUPER_MAGIC, "NFS"},
{SMB_SUPER_MAGIC, "SMB"},
{SYSV2_SUPER_MAGIC, "SYSV2"},
{SYSV4_SUPER_MAGIC, "SYSV4"},
{UFS_SUPER_MAGIC, "UFS"},
{XENIX_SUPER_MAGIC, "XENIX"},
{_XIAFS_SUPER_MAGIC, "XIAFS"},
{0, NULL},
};
static char unknown[100];
int i;
for(i=0; table[i].type != 0; i++)
if(table[i].type == type)
return table[i].name;
sprintf(unknown, "unknown type: %#x", type);
return unknown;
}
/* do_statfs --- Использовать statfs и вывести сведения */
void do_statfs(const struct mntent *fs)
{
struct statfs vfs;
if(fs->mnt_fsname[0] != '/')
return;
if(statfs(fs->mnt_dir, & vfs) != 0)
{
//fprintf(stderr, "%s: %s: statfs failed: %s\n",myname, fs->mnt_dir,stderror(errno));
errors++;
return;
}
printf("%s, mounted on %s:\n", fs->mnt_dir, fs->mnt_fsname);
printf("\tFilesystem type: %s\n", type2str(vfs.f_type));
printf("\tBlock size: %ld\n", (long) vfs.f_bsize);
printf("\tBlocks: %ld\n",(unsigned long)vfs.f_blocks);
printf("\tBlocks free: %ld\n", (unsigned long) vfs.f_bfree);
printf("\tSpace all: %ld\n", (unsigned long) (vfs.f_bsize*vfs.f_blocks));
printf("\tSpace free: %ld\n", (unsigned long) (vfs.f_bsize*vfs.f_blocks));
//printf("\tf_bavail:%ld\n", (unsigned long) vfs.f_bavail);
//printf("\tf_files: %ld\n", (unsigned long) vfs.f_files);
//printf("\tf_ffree: %ld\n", (unsigned long) vfs.f_ffree);
//printf("\tf_namelen: %ld\n", (unsigned long) vfs.f_namelen);
printf("\t--------------------------------\n");
card_ftype = vfs.f_type;
}
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
На мой дилетантский взгляд вот эта конструкция не самая удачная:
"int fd = open("/dev/sdd", O_RDWR);"
тут жесткая привязка к устройству SDD, добавление нового накопителя и Ваша прога будет искать карточку совсем не там.. разумеется для дебага вполне подходит.
Ну а с чистой карточкой я бы отталкивался от факта, что "карточка чистая->нет на ней разделов/партиций"
эту инфу выдает, например, "fdisk -l"
Цитата Есть следущая задача
Устройсво скидывает на карточку(ММС или SD) данные
Но при включении карта должна определиться и если на на ней не фат то отформатироваться
С этим проьлем нет - решил эту задачу
А вот если карта вообще чистая - нет на ней еще разделов
тут я пока в тупике
Прошу помочь
На любой вопрос есть любой ответ.
Бабай
Регистрация: 28.05.2009
Пол: Мужчина
Из: Екатеринбург
Цитата На мой дилетантский взгляд вот эта конструкция не самая удачная:
"int fd = open("/dev/sdd", O_RDWR);"
тут жесткая привязка к устройству SDD, добавление нового накопителя и Ваша прога будет искать карточку совсем не там.. разумеется для дебага вполне подходит.
Ну а с чистой карточкой я бы отталкивался от факта, что "карточка чистая->нет на ней разделов/партиций"
эту инфу выдает, например, "fdisk -l"
Конструкция "int fd = open("/dev/sdd", O_RDWR);"
нормальная так в девай только однак карточка а sdd использовал потому что отлаживал на ПиСюке
sasa
Регистрация: 20.05.2009
Я одно не пойму - нафига тут С :) Это же скриптом на sh или ash несколькими строчками делается. Если все же С нужен а это просто кусок для эксперимента то я бы посмотрел как реализованы dd, fdisk, mkfs в busybox, взял библиотеку lib_bb от busybox и реализовал то что нужно на чистом С без вызовов внешних программ, хотя с mkfs посложней наверно будет, dd - это вообще обычные read и write - код совсем простой.
Цитата А вот если карта вообще чистая - нет на ней еще разделов
тут я пока в тупике
Если хочется продолжать по намеченному пути, то можно просто скопировать mbr с карты где есть разделы и сохранить а потом просто dd ее закидывть если на карте нет разделов, но это если карты одинаковые. Вернее не mbr а mbs - mbr у майкрософт :)
Кстати - "mkfs.vfat" это же просто таблицу fat фактически создать, так что задача то несложная и на С - вместо dd пользоваться read/write, вместо mkfs.vfat почитать faq по fat, таблицу разделов можно вообще налету создавать самому - наверно еще и всего один раздел нужен - там всего 16 байт на раздел, в интернете везде расписано как устроена таблица разделов. в общем я бы посоветовал все равно смотреть исходники busybox- там код краткий и понятный.