Generate a copy of the ACLs currently in memory in the specified filename. * Returns C_OK on success or C_ERR if there was an error during the I/O. * When C_ERR is returned a log is produced with hints about the issue. */
| 1652 | * Returns C_OK on success or C_ERR if there was an error during the I/O. |
| 1653 | * When C_ERR is returned a log is produced with hints about the issue. */ |
| 1654 | int ACLSaveToFile(const char *filename) { |
| 1655 | sds acl = sdsempty(); |
| 1656 | int fd = -1; |
| 1657 | sds tmpfilename = NULL; |
| 1658 | int retval = C_ERR; |
| 1659 | |
| 1660 | /* Let's generate an SDS string containing the new version of the |
| 1661 | * ACL file. */ |
| 1662 | raxIterator ri; |
| 1663 | raxStart(&ri,Users); |
| 1664 | raxSeek(&ri,"^",NULL,0); |
| 1665 | while(raxNext(&ri)) { |
| 1666 | user *u = ri.data; |
| 1667 | /* Return information in the configuration file format. */ |
| 1668 | sds user = sdsnew("user "); |
| 1669 | user = sdscatsds(user,u->name); |
| 1670 | user = sdscatlen(user," ",1); |
| 1671 | sds descr = ACLDescribeUser(u); |
| 1672 | user = sdscatsds(user,descr); |
| 1673 | sdsfree(descr); |
| 1674 | acl = sdscatsds(acl,user); |
| 1675 | acl = sdscatlen(acl,"\n",1); |
| 1676 | sdsfree(user); |
| 1677 | } |
| 1678 | raxStop(&ri); |
| 1679 | |
| 1680 | /* Create a temp file with the new content. */ |
| 1681 | tmpfilename = sdsnew(filename); |
| 1682 | tmpfilename = sdscatfmt(tmpfilename,".tmp-%i-%I", |
| 1683 | (int)getpid(),(int)mstime()); |
| 1684 | if ((fd = open(tmpfilename,O_WRONLY|O_CREAT,0644)) == -1) { |
| 1685 | serverLog(LL_WARNING,"Opening temp ACL file for ACL SAVE: %s", |
| 1686 | strerror(errno)); |
| 1687 | goto cleanup; |
| 1688 | } |
| 1689 | |
| 1690 | /* Write it. */ |
| 1691 | if (write(fd,acl,sdslen(acl)) != (ssize_t)sdslen(acl)) { |
| 1692 | serverLog(LL_WARNING,"Writing ACL file for ACL SAVE: %s", |
| 1693 | strerror(errno)); |
| 1694 | goto cleanup; |
| 1695 | } |
| 1696 | close(fd); fd = -1; |
| 1697 | |
| 1698 | /* Let's replace the new file with the old one. */ |
| 1699 | if (rename(tmpfilename,filename) == -1) { |
| 1700 | serverLog(LL_WARNING,"Renaming ACL file for ACL SAVE: %s", |
| 1701 | strerror(errno)); |
| 1702 | goto cleanup; |
| 1703 | } |
| 1704 | sdsfree(tmpfilename); tmpfilename = NULL; |
| 1705 | retval = C_OK; /* If we reached this point, everything is fine. */ |
| 1706 | |
| 1707 | cleanup: |
| 1708 | if (fd != -1) close(fd); |
| 1709 | if (tmpfilename) unlink(tmpfilename); |
| 1710 | sdsfree(tmpfilename); |
| 1711 | sdsfree(acl); |
no test coverage detected