Mise à jour de /etc/mtab

Bonjour à tous.

Mon amie n’est pas une fan d’informatique et c’est à moi d’administrer
son poste de travail. Je lui ai installer Fluxbox parce qu’il est
simple et rapide. Je lui mâche donc le travail de construction des
menus, etc…

Mon amie s’est dernièrement (enfin) décidée à utiliser une clé USB et
la mémoire de masse de son téléphone portable.

Néanmoins, Fluxbox ne monte pas automatiquement les supports de masse
amovibles. J’ai alors décidé de lui concocter un menu de
montage/démontage pour chaque support.

Les supports utilisés étant toujours les mêmes, j’ai décidé d’utiliser
la capacité de udev à générer un lien symbolique en fonction de l’UUID
du support concerné.

Une solution simple aurait été d’invoquer à partir du menu Fluxbox un
script à base de pmount/pumont.

Mais, comme j’avais envie de me frotter à la programmation système
(juste l’effleurer), j’ai décidé de programmer cela à l’aide de C/C++.

Je dois admettre que le travail à fournir est largement plus
conséquent qu’avec un script! Mais c’est intéressant.

Bon, tout cela pour écrire que mon problème est le suivant (ce n’est
pas le seul, d’autres vont suivre: Lorsque je lance, via le menu, mon
programme concernant la clé USB, j’ai dans le /proc/mounts

/dev/cle_USB_SanDisk_a_Sabine /media/cle_USB_SanDisk_a_Sabine vfat
rw,noexec,relatime,uid=1001,gid=1001,fmask=0022,dmask=0022,codepage=cp437,iocharset=utf8,shortname=mixed,errors=remount-ro
0 0

Mais dans le /etc/mtab, je n’ai rien de ressemblant. En
fait, rien n’a changé.

Je pourrais ajouter la chaîne à l’aide du programme dans le /etc/mtab
puisque le celui-ci s’exécute sous root (via sudo), mais cela ne me
paraît pas très élégant.

Je vous livre ci-joint, le code du programme de montage. Il est simple
et utilise de fonctions du système les unes après les autres. J’ai
commencé par un exemple donné par MisterFreez et de fils en
aiguilles… Cela a donné ça :

//mount.cpp :
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h> 
#include <linux/fs.h>  
#include <errno.h>     
#include <string.h>    
#include <string>      
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <stdio.h>

#include "../classe_etat_disque_movible/etat_disque_movible.h"

int main(int argc, char **argv) {
  using namespace std;

  char disque[] = "/dev/cle_USB_SanDisk_a_Sabine" ;
  char rep_cible[] = "/media/cle_USB_SanDisk_a_Sabine" ;
  char sys_fic[] = "vfat" ;
  uid_t uid = 1001 ;
  gid_t gid= 1001 ;

  if(mkdir(rep_cible, 0777) !=0) {
    etat_disque_amovible eda("Le r\351pertoire n'a pas pu \352tre cr\351\351!", strerror(errno)) ;
    return Fl::run();
    return(-1) ;
  }

  if(chown(rep_cible, uid, gid) != 0) {
    etat_disque_amovible eda("Impossible de changer le nom du r\351pertoire de montage!", strerror(errno)) ;
    return Fl::run();
    return(-1) ;
  }
  
  char option_mount[20] = "uid=" ;
  sprintf(option_mount + strlen(option_mount), "%d", uid);
  strcat(option_mount, ",gid=") ;
  sprintf(option_mount + strlen(option_mount), "%d", gid);

  if (mount(disque, rep_cible, sys_fic, MS_NOEXEC, option_mount) != 0){
    if(rmdir(rep_cible) !=0) {
      etat_disque_amovible eda("Le r\351pertoire de montage n'a pas pu \352tre effac\351!\nVous devrez l'effacer manuellement.", strerror(errno)) ;
      return Fl::run();
    }
    etat_disque_amovible eda("La cl\351 n'a pas pu \352tre mont\351e!\nVeuillez v\351rifier que le support est bien connect\351!", strerror(errno)) ;
    return Fl::run();
    return(-1) ;
  }
}

Une petite boîte de dialogue s’affiche si un problème survient.

etat_disque_movible.h ne sert qu’à construire la boîte de dialogue.

Pour le démontage, le principe reste le même.

En définitive, existe-t-il une façon de dire au noyau de mettre à jour le /etc/mtab ?

Pourquoi veux tu modifier le mtab ?

Si tu veux toucher aux systeme c’est plutôt du coter du language C car la majorité des api son coder dans ce langage, pour le reste des critère c’est trop vague.
cette option si tu la choisi rien que pour cela c’est vraiment pas une bonne idée. il te faut regarder un langage dans son ensemble.

si tu veux monter un disque 2 methode.
1.- Détecter le montage et le faire via un script. pas très pratique et peux fiable si le disque change ou la partition est modifiée…
2.- utiliser un paquet qui gère les montages , je me souviens plus du nom mai sa existe modifier une ou cree une règle udev.

Ensuite 1 topic par problème c est mieux :wink:

D’une part les appels systèmes (je présume que c’est de cela dont tu parle) sont directement accessible en C++ (il a était conçu pour), d’autre part rien oblige à utiliser de manière direct les appels systèmes pour faire de « la programmation système ».

Il l’a choisi pour s’amuser il semble donc, je ne vois pas le problème.

Il n’a qu’une question :wink:

Je te trouve un peu dur avec lui, c’est toujours bien de chercher à en découvrir plus (quelque soit le domaine).

BHOOUU!, c’est vrai ça! :022

Je plaisante bien sûr… Disons que toutes critiques est bonnes à
prendre, pourvu qu’elles ne soient pas bêtes et méchantes. Ça fait
avancer le débat et les connaissances, c’est le principal.

C++ est un véritable couteau suisse, capable de programmation système
ou de très haut niveau. De plus c’est, en gros, la "couche objet"
langage C. Cette dernière affirmation est à peine caricatural.

Même dans les cas extrêmes où il n’y a pas d’utilisation directe prévu
par les concepteurs de bibliothèques C, on toujours la possibilité de
faire :

// Du code C++

extern "C" {
// Du code C
#include "mon_code_C.h"
}

int main()
{
jutilise_mon_code_C() ;
...
} 

Pas toujours facile à mettre en place, mais c’est efficace. Car sans
cela, je n’aurais jamais pu utiliser la bibliothèque ffmpeg, par
exemple. Les auteurs de celle-ci se sont toujours refusés à la
traduire en C++. Et souvent, il existe un wrapper C++.

L’application pmount fait cela très bien. Mais, comme je le disais,
c’est une application “école”, pour le fun en quelques sortes…

Mais, où vois-tu plusieurs topics? Je n’ai posé qu’une
question… J’ai essayé d’être précis : besoin de l’utilisateur, choix
technologiques, une seule problématique à la fois…

Bon, j’envoie très rapidement la réponse à la question de MisterFreez,
mais pose méridienne obligatoire!

Il me semble, mais je m’avance peut-être un peu trop, que mount
utilise /etc/mtab pour afficher les supports montés.

Si je monte à l’aide pmount, j’ai :

 :-)  $ pmount /dev/cle_USB_SanDisk_a_Sabine 
 :-)  $ mount | tail -1
/dev/sdf1 on /media/cle_USB_SanDisk_a_Sabine type vfat (rw,noexec,nosuid,nodev,quiet,shortname=mixed,uid=1000,gid=1000,umask=077,fmask=0177,dmask=0077,utf8,iocharset=iso8859-1)
 :-)  $ pumount /dev/cle_USB_SanDisk_a_Sabine 
 :-)  $ mount | tail -1
AUTRE CHOSE...
 :-)  $ 

Mais lorsque je lance ma petite application et que je fait un mount, le
support est invisible.

Le fait qu’un administrateur ne puisse pas voir ce disque pose
évidemment des problèmes de sécurité.

La question que je me posais, c’est comment fait une application comme
pmount pour que cela s’affiche? J’ai donc pensé logiquement au fichier
mtab.

[quote=“valrik”]La question que je me posais, c’est comment fait une application comme
pmount pour que cela s’affiche? J’ai donc pensé logiquement au fichier
mtab.[/quote]
Ok je comprends. Tu peux voir ce que fait pmount (ou mount qui est probablement plus simple) avec strace peut être.

À retenir cette commande.

Donc quand je fait un :

~# strace pmount /dev/cle_USB_SanDisk_a_Sabine 

J’obtiens entre autres :

open("/etc/mtab", O_RDONLY)             = 3

Read Only, donc ce n’ai pas pmount qui se charge de mettre à jour le /etc/mtab.

Par contre si je fais un :

~# strace mount /dev/cle_USB_SanDisk_a_Sabine /tmp/essai_mount/

J’ai :

...
open("/etc/mtab", O_RDWR|O_CREAT|O_APPEND|O_LARGEFILE, 0666) = 4
umask(022)                              = 077
fstat64(4, {st_mode=S_IFREG|0644, st_size=943, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb775e000
fstat64(4, {st_mode=S_IFREG|0644, st_size=943, ...}) = 0
_llseek(4, 0, [0], SEEK_SET)            = 0
read(4, "/dev/sda8 / ext3 rw,errors=remou"..., 943) = 943
write(4, "/dev/sdf1 /tmp/essai_mount vfat "..., 39) = 39
close(4)                                = 0
...

La ligne write(4, "/dev/sdf1 /tmp/essai_mount vfat "…, 39) est
certainement la clé du problème, par contre je ne sais pas comment
dire à mount() d’écrire dans /etc/mtab.

Je vais essayer de rechercher cela dans la manpage une nouvelle fois, mais…

Euuuhhhh, je mort pas moi :open_mouth:
J’ai mal lu ton poste désoler si j’ai quelque peux déraper car j’ai croiser avec un autre poste :005

Vu comme ça, je dirais que wrapper du C pour en faire du C++ … et pourquoi réinventer la roue , c est sure que tu peux faire sans mai bon …
Si c est pour faire du système c’est pas vraiment aproprier… comment explique tu que le kernel est fait en C en très grande partie et que sa continue :think:

Pas besoin de connaitre le le C pour faire du C++ , le c++ reste compatible avec le C
vala

Salut Panthere.

Je vais te répondre en faisant référence “à mon petit paradigme à moi
personnellement”. :wink:

Tous simplement parce-que le C++ est plus sûr que le C. Les
débordements de tampons en C sont une véritable plaie! De ce fait, il
peut en résulter des failles de sécurité majeures.

Avec le C++ et sa STL, on s’affranchit grandement de ces problèmes.

Les problèmes liés aux pointeurs sont aussi grandement résolus grâce
aux SmartPointers. Grandement, pas complètement, malheureusement…

Par exemple, utiliser un objet string “s’autogère” du point de vue de
la mémoire. C’est très confortable. Et la fonction c_str() permet de
convertir sans problème cet objet en chaîne type langage C.
voir :

cplusplus.com/reference/string/string/c_str/

C’est ce que j’aurais du faire dans mon code, mais pour l’instant ce
n’est encore que du bricolage.

A quoi bon ré-écrire quelque chose qui fonctionne très bien? Par
contre, certains nouveaux modules sont écrits en C++. J’avais un
pilote de carte ISDN qui était écrit dans ce langage.

Voilà, j’espère avoir répondu avec clarté à tes questions. :slightly_smiling:

Merci pour tes réponses je suis tout a fait daccords, le c++ est l’évolution du C avec ces avantages. il n’en reste cepandant pas moins que le kernel est fait en C le problème c est que sa continue… je pense que depuis le temps cela aurait du changer…