我为此疯狂。 我正在尝试编写一个可以存储和提取文件的存档库。存档文件如下所示:
<0,/home/user/file.txt,154,0755>
file contents (154 byte)
每个文件由标题(&lt; ...&gt;)标识,带有四个“标记”(以逗号分隔),文件类型(0表示文件,1表示目录),路径,大小(字节),权限(八进制)。 我使用stat系统调用检索大小和权限(我在Linux上)。 我的问题是我必须将八进制值从st_mode转换为字符串,将其存储在存档文件(标题中的第四个标记)中,然后将其解压缩并与chmod系统调用一起使用。
要将其转换为字符串我使用:
char mode[6];
sprintf (mode, "%o", statr.st_mode);
并检索它我使用atoi,但它似乎不起作用。例如,存储在第4个标记中的值是100644,但是chmod将权限设置为错误(文件不能被我的用户读取)。
我不确定我是否解释得很好,如果需要,我会发布整个代码(但是它不认为存在实现问题,只是从八进制转换为字符串之间的问题)
编辑:解决了!实际上strtol方法有效,但我忘了将它也应用到目录中(因此,由于文件夹的权限掩码错误,因此提取内部文件导致Segfault的目录)。谢谢大家的帮助!
答案 0 :(得分:1)
据我所知,这不是一个unix标准函数。
您很可能必须屏蔽st_mode
才能获得您想要的每个权限位,并将其翻译成对您有意义的内容。
这可能是一种更简单的方法,但是我已经包含了一个简单的例子,它展示了如何获得您感兴趣的每一位。这会编译并且似乎按预期运行。< / p>
<强> st_mode.c 强>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define SET_UID_BIT 0x4000
#define SET_GID_BIT 0x2000
#define STICKY_BIT 0x1000
// Readable USER bits defined here
#define USR_READ_BIT 0x400
#define USR_WRITE_BIT 0x200
#define USR_EXEC_BIT 0x100
// Readable GROUP bits defined here
#define GRP_READ_BIT 0x040
#define GRP_WRITE_BIT 0x020
#define GRP_EXEC_BIT 0x010
// Readable OTHER bits defined here
#define OTH_READ_BIT 0x004
#define OTH_WRITE_BIT 0x002
#define OTH_EXEC_BIT 0x001
int main()
{
// The file I'm opening
const char fp[] = "myfile.txt"; // -rw-rw-r--
struct stat stats;
// Get the stats
if ( 0 == stat( fp, &stats ) )
{
// store st_mode
mode_t mode = stats.st_mode;
// init printable_mode
unsigned int printable_mode = 0;
// Test for each permission bit in mode.
// If the bit is present, mark the corresponding bit in printable_mode
// using defined bits above.
if( mode & S_ISUID )
printable_mode |= SET_UID_BIT;
if( mode & S_ISGID )
printable_mode |= SET_GID_BIT;
if( mode & S_ISVTX )
printable_mode |= STICKY_BIT;
if( mode & S_IRUSR )
printable_mode |= USR_READ_BIT;
if( mode & S_IWUSR )
printable_mode |= USR_WRITE_BIT;
if( mode & S_IXUSR )
printable_mode |= USR_EXEC_BIT;
if( mode & S_IRGRP )
printable_mode |= GRP_READ_BIT;
if( mode & S_IWGRP )
printable_mode |= GRP_WRITE_BIT;
if( mode & S_IXGRP )
printable_mode |= GRP_EXEC_BIT;
if( mode & S_IROTH )
printable_mode |= OTH_READ_BIT;
if( mode & S_IWOTH )
printable_mode |= OTH_WRITE_BIT;
if( mode & S_IXOTH )
printable_mode |= OTH_EXEC_BIT;
// Let's see what it looks like....
printf("%04x\n", printable_mode);
printf("%x\n", mode);
}
return 0;
}
答案 1 :(得分:0)
如果您使用前导0
以八进制编写数据,则可以使用strtol
阅读它:
char mode[8];
snprintf(mode, 8, "0%o", statr.st_mode);
strtol(mode, NULL, 0);
或者,您可以使用strtol
提供8
作为base
参数来阅读,在这种情况下,前导0
是不必要的:
char mode[7];
snprintf(mode, 8, "%o", statr.st_mode);
strtol(mode, NULL, 8);
答案 2 :(得分:0)
使用strtoul。例如,以下测试程序正确地解释“100644”(八进制)。
转换后,*endptr
指向第一个未转换的字符。如果*endptr == 0
,整个字符串已被消耗,否则出现错误(例如,调用strtoul,“1234X”停在'X')。请注意,八进制10644等于33188(十进制)。
#include <stdlib.h>
#include <stdio.h>
int main() {
char *s = "100644";
char *endptr;
unsigned long result = strtoul(s, &endptr, 8);
if (*endptr)
printf("conversion error!\n");
printf("result: %lu == octal %lo\n", result, result);
return 0;
}