Application of Linux Programming Learning Note----File Management Example

Source: Internet
Author: User
Tags lstat sprintf strcmp strlen

I. Using LS-L to sort output directory information 1. Requirements and knowledge point coverage

The ls-l command lists the basic information for a file, which is the directory, according to the following parameters.

If there is no specific directory or file, then list all the non-hidden files in the current directory information, including file type, file permissions, number of hard links, owner. Owner's group, file size, file update time, and so on.

such as:

If no file is specified, the file information in all directories is output:

Therefore, the basic functions and the required knowledge points of this application are:

① parameter check. Including the number of parameters check, if there are multiple files and directories need to list information, then traverse all the parameters, also need to read the current parameter is a file or directory. (stat function can be read)

② if it is an ordinary file, you need to build a linked list of this file, and then use the stat () function to read the properties of the linked list member file and convert the user ID to the user name based on the stat output, the conversion of the group ID to the group name, and the conversion of the time (Stat function time is Linux time, The number of seconds from 1970-1-1 to the moment).

③ if it is a directory file, you need to read the list of files in the directory one at a time and store them on demand in the linked list, this example chooses a simple insert sort, and then reads the basic information of the file.

2. Process

The main function flow is as follows:

① parameter check. The parameter cannot be less than two, and if the parameter is greater than two, the corresponding information is listed.

The ② detects the parameter type and, if it is a normal file, reads the file's properties.

③ if it is a directory file, loop through all the files in the directory, use and simple insert sort to read the information, and list the entire linked list file information.

3. Code implementation

The specific code is as follows, the detailed procedure that see comment.

/*************************************************************************> File name:sort_l.c> Author: Suool> Mail: [email protected]> Created time:2014 July 31 Friday 15:44 32 seconds *********************************** /#include <stdio.h> #include <stdlib.h> #include <dirent.h># include<string.h> #include <sys/stat.h> #include <time.h> #include <pwd.h> #include <grp.h     > #define NAME_SIZE 256//Constructs a linked list node data structure struct fnode{struct fnode *next;   Next member Char Name[name_size]; Current member file name};struct fnode *insert_list (struct fnode *temp,struct fnode *head) {if (head==null)//if linklist is empty,for tem P is the first One{head=temp;return head;} if (strcmp (temp->name,head->name) <0)//temp'll be insert before first one{temp->next=head;head=temp; return head;} struct Fnode *next=head->next;struct fnode *prev=head;while (next!=null&& strcmp (temp->name,next-> Name) {>0) {next=next->next;prev=prev-&Gt;next;} Temp->next=next;prev->next=temp;return Head;} Read File permission attribute function, eradicate parameter (Lstat function return type St_mode) List the permissions of each file type character output_type_perm (mode_t mode) {char type[7]={' P ', ' C ', ' d ', ' B ', ' -', ' l ', ' s '};int index= ((mode>>12) & 0xF)/2;printf ("%c", Type[index]); char *perm[8]={"---", "--x", "-w-", "- WX "," r--"," R-x "," rw-"," rwx "};//rwxprintf ("%s ", Perm[mode>>6 &07]);p rintf ("%s ", Perm[mode>>3 & ]);p rintf ("%s", perm[mode>>0 &07]);} Lists the user and group void Output_user_group (uid_t uid,gid_t gid) {struct passwd *user;user=getpwuid (UID);p rintf ("%s", User->pw_ name), struct group *group;group=getgrgid (GID);p rintf ("%s", Group->gr_name);} The list of file basic information functions outputs the return value of each function on the screen output_mtime (time_t mytime) {char buf[256];memset (buf, ' n ', ' Ctime_r '); BUF); Buf[strlen (buf) -1]= ' + ';//memcpy (Buf,ctime (MyTime), strlen (CTime (MyTime))-1);p rintf ("%s", buf);} void Output_info (struct fnode *head) {struct Fnode *temp=head;while (temp!=null) {struct stat mystat;if ( -1==stat (temp- >name,&mystat)) {perror ("Stat "); exit (exit_failure);} Output_type_perm (Mystat.st_mode);p rintf ("%4d", Mystat.st_nlink); Output_user_group (Mystat.st_uid,mystat.st_gid); printf ("%8ld", Mystat.st_size), Output_mtime (mystat.st_mtime);p rintf ("%s\n", temp->name); temp=temp->next;}} void Free_list (struct fnode *ptr) {struct Fnode *temp=ptr;struct fnode *link=ptr;while (PTR) {temp=ptr;ptr=ptr->next; Free (temp);}} Main () function source int main (int argc,char *argv[]) {if (ARGC < 2) {printf ("Usage:%s dir_name\n", argv[0]); exit (Exit_failure) ;} int I;for (i=1;i<argc;i++) {struct Fnode *linklist=null;struct stat stat_info;if (stat (argv[i],&stat_info) ==-1) {perror ("stat"); exit (exit_failure);} if (S_isreg (stat_info.st_mode))//regular file{struct fnode *temp= (struct Fnode *) malloc (sizeof (struct fnode)); if (NULL ==temp) {perror ("malloc"); exit (exit_failure);} Temp->next=null;memset (temp->name, ' name_size '), memcpy (Temp->name,argv[i],strlen (argv[i)); linklist =insert_list (temp,linklist); Output_info (linklist);//output Information of thE File}else if (S_isdir (Stat_info.st_mode)) {char buf[name_size];getcwd (buf,128);D ir *dirp=null;dirp=opendir (Argv[i] if (NULL==DIRP) {perror ("Opendir"); exit (exit_failure);} struct Dirent *entp=null;while (Entp=readdir (dirp)) {struct Fnode *temp= (struct Fnode *) malloc (sizeof (struct fnode)); (null==temp) {perror ("malloc"); exit (exit_failure);} Temp->next=null;memset (temp->name, ' name_size '); memcpy (Temp->name,entp->d_name,strlen (entp->d _name)); Linklist=insert_list (temp,linklist);} ChDir (Argv[i]);//change the current dirctoryclose (DIRP); Output_info (linklist); chdir (BUF);} Free_list (linklist);} return 1;}

Operation Result:


Ii. Implementing the Tree System command 1. Problem analysis

The tree command in Linux allows you to list all of the asking prices and directory names in a given directory in the form of trees, as shown below:


We are going to implement such a tree command. The basic process is as follows:

(1) Initialization of the system. Constructs an empty queue that caches files that are not output in the entire directory (containing subdirectories) in real time.

(2) Read all the file information and directory information in the directory, and construct a new sub-sort queue According to the ASCII code value.

(3) The sub-queue is merged with the whole directory queue, the method is similar to the operation of the stack, the whole sub-queue is added to the front of the original queue, update the global queue information.

(4) Out of the queue. Reads the properties of the first member of a queue. If it is a file, just press the information output, if it is a directory, repeat the above (2) (3) (4) step. Recursive loop operation.

2. Program Flowchart



3. Code

For the recursive section, the application applet similar to the previously written recursive copy directory file.

<pre name= "code" class= "CPP" > #include <stdio.h> #include <stdlib.h> #include <string.h># Include <sys/stat.h> #include <dirent.h> #include <fcntl.h> #include <errno.h> #define Regu_   File 1#define dir_file 2//constructs a stack structure in which each node represents a document, and the node data structure is defined as follows: typedef struct node{struct node *next;  Next node, construct single-chain structure unsigned int level;          The depth of the current subdirectory, used to differentiate the hierarchical char *name at output;     The file name under the directory, does not contain a parent directory, for the output name Char *fullname;   Outputs the entire pathname for the Read Property}filenode;//queue data structure typedef struct head{struct node *head;   Team first pointer struct node *rear; The tail pointer}headnode;void dir_tree (char *dirname,headnode *link_stack, int level); int Insert_sort (Headnode *link_stack,    Filenode *new) {Filenode *next = link_stack->head;    Filenode *prev = NULL;            while (next) {if (strcmp (New->name, Next->name) > 0) {prev = next;        Next = next->next;    } else break; } if (Link_stack->head = = NULL &&amP        Link_stack->rear = = NULL)//the first one {link_stack->head = NEW;    Link_stack->rear = NEW; } else if (prev = = NULL && next! = null)//insert in front of the queue {New->next = Link_stack-&gt        ; head;    Link_stack->head = NEW;    } else if (prev! = null && next = null)//insert in end of the queue.        {prev->next = NEW;    Link_stack->rear = NEW;        } else {prev->next = NEW;    New->next = Next;    }}headnode *read_dir_to_link_stack (char *dir,int level) {dir *dirp = NULL;    if (null== (Dirp=opendir (dir))) {perror ("Opendir"); exit (Exit_failure);    } Headnode *ptr = (Headnode *) malloc (sizeof (Headnode));    if (ptr==null) {perror ("malloc"); exit (Exit_failure);    } ptr->head = NULL;    Ptr->rear = NULL;    struct Dirent *entp = NULL; while (NULL! = (entp =readdir (DIRP))) {if (strcmp (Entp->d_name, "...") ==0 | | strcmp (entp->D_name, ".") ==0)//ignore./...        /{continue;            } else {Filenode *temp = (Filenode *) malloc (sizeof (Filenode));            if (temp==null) {perror ("malloc"); exit (Exit_failure);            } temp->next = NULL;            Temp->level = level;            Temp->name = (char *) malloc (strlen (entp->d_name) + 1);            sprintf (Temp->name, "%s\0", entp->d_name);            Temp->fullname = (char *) malloc (strlen (dir) +1+strlen (entp->d_name) + 1);            sprintf (Temp->fullname, "%s/%s\0", dir,entp->d_name);        Insert_sort (ptr,temp);    }} closedir (DIRP); return ptr;} /*type:1, Regufile.    2 dir.*///output The information format of a file void Out_file_info (filenode *ptr, int type) {int i;    printf ("|");    for (i = 0;i < ptr->level; i++) {printf ("");    } printf ("|--"); printf ("%s\n", Ptr->name);} void Pop_file_tree (Headnode *link_stack) {while (Link_stAck->head = NULL)//Traverse all nodes {struct stat stat_src; if (Lstat (Link_stack->head->fullname, &stat_src)! = 0) {fprintf (stderr, "%s" (%d): Stat error (        %s)!\n ", __file__, __line__, Strerror (errno)); } if (S_isdir (Stat_src.st_mode))//directory, call dir_tree function {Filenode *temp = link_stack->h            ead            Link_stack->head = link_stack->head->next;            if (Link_stack->head = = NULL) link_stack->rear ==null;            Out_file_info (Temp,dir_file);            Dir_tree (Temp->fullname,link_stack,temp->level);            Free (temp->name);            Free (temp->fullname);        Free (temp);            } else//Otherwise output file {Filenode *temp = link_stack->head;            Link_stack->head = link_stack->head->next;            if (Link_stack->head = = NULL) link_stack->rear ==null;Out_file_info (Temp,regu_file);            Free (temp->name);            Free (temp->fullname);        Free (temp);    }}//Output Directory and subdirectory information recursive function void Dir_tree (char *dirname,headnode *link_stack, int level) {Headnode *ret = NULL;        Reads the directory information, returns a sort queue, each node in the queue includes the file name of the child file and the entire path of ret = Read_dir_to_link_stack (dirname, level+1); Merges the original queue with the new return queue, placing the new return queue before the original queue, similar to the stack action if (link_stack->head! = NULL && Ret->head! = null) {ret-&        Gt;rear->next = link_stack->head;    Link_stack->head = ret->head;    } if (Link_stack->head = = NULL && Ret->head! = null) Link_stack->head = ret->head;    if (link_stack->rear = = NULL && ret->rear! = null) Link_stack->rear = ret->rear;    Free (ret); Pop_file_tree (link_stack);} int main (int argc,char *argv[]) {if (argc! = 2)//If not given directory {fprintf (stderr, "pls useage%s dir_name\n",    Argv[0]); exit (Exit_failure);    } struct stat stat_src; if (LSTAt (Argv[1], &stat_src)! = 0)//Read file property {fprintf (stderr, "%s": Stat error (%s)!\n ", __file__, __line__,        Strerror (errno));    Exit (Exit_failure); } if (S_isreg (stat_src.st_mode))//regular file, error {fprintf (stderr, "%s [Error opening dir]\n", Argv[1]); Exit (    Exit_failure); } else if (S_isdir (Stat_src.st_mode))//directory file {headnode *link_stack = (Headnode *) malloc (sizeof (head        node));        if (Link_stack = = NULL) {perror ("malloc"); exit (Exit_failure);        } link_stack->head = NULL;        Initialize Global queue link_stack->rear = NULL;        printf ("%s\n", argv[1]);  Dir_tree (argv[1], link_stack,-1);             Execute function free (link_stack); Complete, recycle memory} else return 1;}




Operation Result:


Next

Terminal and serial programming

Linux process management and program development

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.