Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the functionality of Preserved Comments in cupsd.conf when cups… #640

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

Ankit3002
Copy link

…ctl is used with command line arguments

@Ankit3002
Copy link
Author

Ankit3002 commented Mar 23, 2023

@zdohnal I made the changes as you requested. Now I 'm printing the comment whenever I read it from cupsd.conf file. I delete the useless commits of Last PR and erroneously drop the last PR. Please review this PR and do let me know if these changes are fine or not ?

Copy link
Member

@zdohnal zdohnal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we can simplify the PR a little bit more - we can get comments via line itself.

cups/adminutil.c Outdated
@@ -698,8 +700,11 @@ cupsAdminSetServerSettings(
if (server_port <= 0)
server_port = IPP_PORT;

while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
while (_cupsFileGetConfAndComments(cupsd, line, sizeof(line), &value, &linenum, comment, sizeof(comment)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about returning the comment via line parameter and remove the new additional parameters? Then the comment printout can happen via last cupsFilePrintf(). WDYT?

cups/file.c Outdated
*/

if ((ptr = strchr(buf, '#')) != NULL)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go with passing comments via line, we can detect the comment, then remove the leading and trailing whitespaces and return buf.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zdohnal I made the changes as you requested. Now I 'm using line variable to get comments. Please review them.

Copy link
Member

@zdohnal zdohnal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't change the behavior of public function - I'm sorry if my comment sounded like it, I still meant to use a new private function.

Additionally we have to take care of adding comments in cupsAdminSetServerSettings().

cups/adminutil.c Outdated
@@ -700,6 +702,16 @@ cupsAdminSetServerSettings(

while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ankit3002 We can't change the behavior of public function like below.

The idea was to have a new internal function, which has the same arguments as cupsFileGetConf(), but it will be able to return comments via line array. In general, it will be almost similar functionality as cupsFileGetConf(), but it will return comment line (without leading and trailing whitespaces) as well as normal lines.

cups/adminutil.c Outdated
@@ -700,6 +702,16 @@ cupsAdminSetServerSettings(

while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
{
if (strchr(line, '#') != NULL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several issues:

  1. linenum checking looks irrelevant
  2. once a new function returns comment line, you can check the first character
  3. the conditional should be part of the if- else if - else control structure below - then you don't need to check for # again in the end
  4. you should use indent variable when printing the line, as it is done in other cupsFilePut()s to have the correct indentation in the cupsd.conf

cups/file.c Outdated
@@ -769,6 +769,7 @@ cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
ptr --;
}

return (buf);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes behavior of public function, we mustn't do that. We need new internal function.

cups/file.c Outdated
@@ -769,6 +769,7 @@ cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
ptr --;
}

return (buf);
*ptr = '\0';
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally you should review every cupsFilePut() below in cupsAdminSetServerSettings() which add a comment - once we start supporting comments, we can't put new comments in.

Rephrase the comments mentioned in cupsFilePut() and put it to the proper place at conf/cupsd.conf.in, f.e. when line contains "" and we are in /admin location:

The code:

  if (remote_admin)
          cupsFilePuts(temp, "  # Allow remote administration...\n");
  else
          cupsFilePuts(temp, "  # Restrict access to the admin pages...\n");

The default cupsd.conf.in:

# Restrict access to the admin pages...
<Location /admin>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
</Location>

so once you remove the cupsFilePut(), update the cupsd.conf.in to look like this f.e.:

# Access to the admin pages:
# - default action defined by Order', see 'man cupsd.conf'
# - use 'Allow'/'Deny' for configuring access
<Location /admin>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
</Location>

Copy link
Author

@Ankit3002 Ankit3002 Mar 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if (in_root_location && (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0)) { wrote_root_location = 1;

if (remote_admin > 0 && share_printers > 0)
      cupsFilePuts(temp, "  # Allow shared printing and remote "
                     "administration...\n");
else if (remote_admin > 0)
      cupsFilePuts(temp, "  # Allow remote administration...\n");
else if (share_printers > 0)
      cupsFilePuts(temp, "  # Allow shared printing...\n");
else if (remote_any > 0)
      cupsFilePuts(temp, "  # Allow remote access...\n");
else
      cupsFilePuts(temp, "  # Restrict access to the server...\n");

    cupsFilePuts(temp, "  Order allow,deny\n");

if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
{
  if (remote_any >= 0)
    cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
  else
    cupsFilePrintf(temp, "  Allow %s\n", old_remote_any > 0 ? "all" : "@LOCAL");
}
  }`

@zdohnal for the above part what should be the comment that I need to write in conf/cupsd.conf.in ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example:

# Access to the server root (/):
# - default action defined by 'Order', see 'man cupsd.conf'
# - use 'Allow'/'Deny' for configuring access
# - allowing access is required for printer sharing or remote administration

@Ankit3002
Copy link
Author

Ankit3002 commented Mar 29, 2023

@zdohnal I made the changes as you requested. I create a private Api to read comments and lines.

  1. The private api is using same line variable to read both comments and configurations.
  2. I changed the comments in cupsd.conf.in as well.
  3. I moved the if else block at the end as well. Linenum checking is used only to not include blank lines between multiline comments.

@Ankit3002
Copy link
Author

Ankit3002 commented Apr 2, 2023

@zdohnal I made the changes as you requested.
1.I create a private Api to read comments and lines.
2. The private api use same line variable to read both comments and configurations.
3. I changed the comments in cupsd.conf.in as well.
4. I moved the if else block at the end as well. Linenum checking is used only to not include blank lines between multiline comments.

@zdohnal Any update on this ?

@zdohnal
Copy link
Member

zdohnal commented Apr 3, 2023

Hi @Ankit3002 ,

I'm sorry, I was on vacation - I'll review this today or tomorrow.

@Ankit3002
Copy link
Author

Hi @Ankit3002 ,

I'm sorry, I was on vacation - I'll review this today or tomorrow.

No issues !

@Ankit3002
Copy link
Author

@zdohnal cupsd.conf.in file is placed in .gitignore, should I remove it from there ? as I won't be able to push the changes in cupsd.conf.in because of this

@zdohnal
Copy link
Member

zdohnal commented Apr 3, 2023

Are you sure? I don't see the file in .gitignore.

@Ankit3002
Copy link
Author

Are you sure? I don't see the file in .gitignore.

I 'm sorry , I got confused it with cupsd.conf

@zdohnal
Copy link
Member

zdohnal commented Apr 4, 2023

@zdohnal I made the changes as you requested. I create a private Api to read comments and lines.

1. The private api is using same line variable to read both comments and configurations.

Ok, please update the comments and debug printf to match the new function - since it was copied from cupsGetConf(), the comments+debugs stayed the same.

2. I changed the comments in cupsd.conf.in as well.

cupsAdminSetServerSettings() still puts comments into cupsd.conf file, which we can't allow once we support reading comments in the functions (otherwise we would end up with duplicity and bigger and bigger cupsd.conf with every cupsctl call).
Please remove the other cupsFilePuts() which add comments from the function and migrate them into sane comments in cupsd.conf.in where it is possible.

3. I moved the if else block at the end as well. Linenum checking is used only to not include blank lines between multiline comments.

I would let blank lines between comments as it is - people adds blank lines between comments for readability, and the code will be simpler.

More comments in the review in the moment.

cups/adminutil.c Outdated
cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
{
if (strchr(line, '#') == NULL)
cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in the comment, I would let here the simple cupsFilePrintf() as it was there - the code will be simpler and we get rid of the new variable.

cups/file.c Outdated
*/

DEBUG_printf(("2cupsFileGetConf(fp=%p, buf=%p, buflen=" CUPS_LLFMT
", value=%p, linenum=%p)", (void *)fp, (void *)buf, CUPS_LLCAST buflen, (void *)value, (void *)linenum));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remains of copy&paste :)

cups/file.c Outdated
@@ -842,6 +842,142 @@ cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
}


/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the function definition to an alphabetically correct place in the file (under _cupsFileCheckFilter())

cups/file.c Outdated
}

/*
* Read the next non-comment line...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy&paste remain...

cups/file.c Outdated
(*linenum) ++;

/*
* Strip any comments...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy and paste leftover.

cups/file.c Outdated
}

return (buf);
*ptr = '\0';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will become a dead code if we return before that.

Additionally I've realized we should deal with inline comments in case they appear (even though they are prohibited by cupsd.conf man page) in a way.

So I propose:

  • check whether there is text before '#':
    • if there is, strip the comment, since it is invalid and process further in the function and return the text before the '#' char
    • if there is only whitespace before '#', strip the leading whitespace and return the comment.

So the block if ((ptr = strchr(buf, '#')) != NULL) can become a handler for inline comments, which will strip the comment in case there is text before it, and the execution will process further.

cups/file.c Outdated

if (buf[0])
{
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we could check whether the first char is # and if so, return buf. With appropriate comment.

@Ankit3002
Copy link
Author

Ankit3002 commented Apr 5, 2023

@zdohnal I made the changes as you requested. Please review.
This is how it works:

  1. I am checking whether the line i 'm reading is comment or not .
  2. if it's a comment than, than i will check for inline comments, and returns the text before '#' as you asked above. ... if it's a simple comment than i simply returns it.
  3. if it's not a comment , than I read the configurations according to the earlier function.
  4. Also now the function would take care about blank lines as well.
  5. I have also placed the function at correct alphabetical order in file.c

@zdohnal
Copy link
Member

zdohnal commented Apr 6, 2023

@zdohnal I made the changes as you requested. Please review. This is how it works:

1. I am checking whether the line i 'm reading is comment or not .

2. if it's a comment than, than i will check for inline comments, and returns the text before '#' as you asked above. ... if it's a simple comment than i simply returns it.

You can simplify it a lot - inline comments are forbidden, so we can remove them and process as cupsGetConf() did. So in general check for '#' and then iterate over the array towards the start - if there is another text before the #, remove the # and text after # comment, don't return and let the function process the text before #.
In case there is no text, let the function process further - it will remove the leading whitespace and in if (buf[0]) scope you check if the first char is # - if it is - return the buf.

In the current code there lot of duplicit code, which can be simplified by the algorithm above.

3. if it's not a comment , than I read the configurations according to the earlier function.

4. Also now the function would take care about blank lines as well.

5. I have also placed the function at correct alphabetical order in file.c

There are still more cupsFilePuts() which have to be removed from function and added to cupsd.conf.in if it makes sense.

There are public holidays in my country, I'll be back on Tuesday.

@Ankit3002
Copy link
Author

Ankit3002 commented Apr 8, 2023

@zdohnal I made the changes as you requested. Please review. This is how it works:

1. I am checking whether the line i 'm reading is comment or not .

2. if it's a comment than, than i will check for inline comments, and returns the text before '#' as you asked above. ... if it's a simple comment than i simply returns it.

You can simplify it a lot - inline comments are forbidden, so we can remove them and process as cupsGetConf() did. So in general check for '#' and then iterate over the array towards the start - if there is another text before the #, remove the # and text after # comment, don't return and let the function process the text before #. In case there is no text, let the function process further - it will remove the leading whitespace and in if (buf[0]) scope you check if the first char is # - if it is - return the buf.

In the current code there lot of duplicit code, which can be simplified by the algorithm above.

3. if it's not a comment , than I read the configurations according to the earlier function.

4. Also now the function would take care about blank lines as well.

5. I have also placed the function at correct alphabetical order in file.c

There are still more cupsFilePuts() which have to be removed from function and added to cupsd.conf.in if it makes sense.

There are public holidays in my country, I'll be back on Tuesday.

@zdohnal I simplified the logic as you requested, Please review them when you will be back from holidays, thank you!
Now,The only cupsFilePuts() in adminutil.c are the ones which are used to write missing info.

@Ankit3002
Copy link
Author

@zdohnal I made the changes as you requested. Please review. This is how it works:

1. I am checking whether the line i 'm reading is comment or not .

2. if it's a comment than, than i will check for inline comments, and returns the text before '#' as you asked above. ... if it's a simple comment than i simply returns it.

You can simplify it a lot - inline comments are forbidden, so we can remove them and process as cupsGetConf() did. So in general check for '#' and then iterate over the array towards the start - if there is another text before the #, remove the # and text after # comment, don't return and let the function process the text before #. In case there is no text, let the function process further - it will remove the leading whitespace and in if (buf[0]) scope you check if the first char is # - if it is - return the buf.
In the current code there lot of duplicit code, which can be simplified by the algorithm above.

3. if it's not a comment , than I read the configurations according to the earlier function.

4. Also now the function would take care about blank lines as well.

5. I have also placed the function at correct alphabetical order in file.c

There are still more cupsFilePuts() which have to be removed from function and added to cupsd.conf.in if it makes sense.
There are public holidays in my country, I'll be back on Tuesday.

@zdohnal I simplified the logic as you requested, Please review them when you will be back from holidays, thank you! Now,The only cupsFilePuts() in adminutil.c are the ones which are used to write missing info.

@zdohnal Any update on above ?

Copy link
Member

@zdohnal zdohnal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the comments in the code and there are still cupsFilePuts() which insert comments, which mustn't happen.

cups/file.c Outdated
if ((ptr = strchr(buf, '#')) != NULL)
{
int index = (int) (ptr - buf);
for(int i=index-1; i>=0; i--)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style issues (spaces)

cups/file.c Outdated
for(int i=index-1; i>=0; i--)
if (!_cups_isspace(buf[i]))
{
buf[index] = '\0';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should put NULL terminator instead of last whitespace in this case.

cups/file.c Outdated
* See if there is anything left...
*/

if (buf[0] != '#')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to check whether there is anything in the buffer, and if so, check for # - this big if-else block is unnecessary and add unnecessary indentation - the good practice is to not nest the code too much, the code should be as straight as possible.

if (buf[0])
{
  // return comment if any
  if (buf[0] == '#')
    return ptr;

  /*
   * Otherwise grab any value and return...
   */
....

cups/adminutil.c Outdated
@@ -800,8 +792,7 @@ cupsAdminSetServerSettings(
wrote_policy = 1;

if (!user_cancel_any)
cupsFilePuts(temp, " # Only the owner or an administrator can "
"cancel a job...\n"
cupsFilePuts(temp,
" <Limit Cancel-Job>\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this into the previous line.

cups/adminutil.c Outdated
@@ -991,8 +951,7 @@ cupsAdminSetServerSettings(
wrote_policy = 1;

if (!user_cancel_any)
cupsFilePuts(temp, " # Only the owner or an administrator can cancel "
"a job...\n"
cupsFilePuts(temp,
" <Limit Cancel-Job>\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this into the previous line.

cups/file.c Outdated
@@ -22,6 +22,7 @@
#include "debug-internal.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <stdbool.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for bool.

@Ankit3002
Copy link
Author

@zdohnal I simplified the code according to the above suggestions, Please review them. Thank you !

cups/file.c Outdated
{
int index = (int) (ptr - buf);
while (index > 0 && _cups_isspace(buf[index]))
buf[index--] = '\0';
Copy link
Member

@zdohnal zdohnal Apr 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. setting the NULL terminator in every iteration is redundant - set it only once you know there is a non-whitespace character before #.
  2. have you tested the code for a line " # comment"? What happens for such a line with the current code?
  3. what will happen if escaped # appears? - # - this is not a comment.
  4. do you think this can be solved with pointer arithmetic instead of introducing a new variable index?

Help: look at cupsFileGetConf() how it solves those situations, think about what is needed in our case, adjust it accordingly and use it here.

cups/file.c Show resolved Hide resolved
cups/file.c Outdated

if (buf[0])
{
// return comment if any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that I used it in my pseudocode, but on a second thought it looks out of place when all other one line comments are written as multiline comments. Would you mind turning it into multiline comment and rephrase the comment, so it looks like proper English instead of a personal note :D .

cups/file.c Outdated
@@ -335,6 +335,131 @@ _cupsFileCheckFilter(
#endif /* !_WIN32 */


/*
* 'cupsFileGetConfAndComments()' - Get line and comments from a configuration file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name in the comment doesn't match with the function definition.

cups/file.c Outdated

return (buf);
}
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The snippet I've provided in the previous review was pseudocode - not actual code which you can put into the code and have it done, but a code which is supposed to express an idea and has to be adjusted for actual source code.
Additionally I mentioned the if-else structure you introduced in the previous commit is redundant. Think about which part could be removed.

@Ankit3002
Copy link
Author

@zdohnal Please review the changes that i made. Thanks!

  1. Now the code is using pointer arithmetic, there is no use of index variable.
  2. I removed the if-else block and simplified the code.
  3. I corrected the function definition

cups/file.c Outdated
*/
if ((ptr = strchr(buf, '#')) != NULL)
{
ptr--;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to move the pointer, if you check the character before your current position - see cupsFileGetConf

cups/file.c Outdated
if ((ptr = strchr(buf, '#')) != NULL)
{
ptr--;
while(ptr >= buf)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will get an address in ptr which is before buf pointer with this conditional. Please fix it.

cups/file.c Outdated
break;
}
ptr--;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing handling of escaped # .

cups/file.c Show resolved Hide resolved
@Ankit3002
Copy link
Author

Ankit3002 commented Apr 17, 2023

@zdohnal I resolved the above issues... Now code will also takes care of line like this "--#--something" since this is not an inline comment so it won't get remove.
also i put back the if block , please review Thank you for the above clarification !
The code for removing inline comment look like this

    /*
     * Remove the inline comment...
     */
     if ((ptr = strchr(buf, '#')) != NULL && _cups_isspace(*(ptr-1)))
     {
        while(ptr > buf)
        {
         // Null-terminate the string after the last non-whitespace
         if(!_cups_isspace(*(ptr-1)))
         {
           *ptr = '\0';
           break;
         }
         ptr--;
        }
     }

cups/file.c Outdated Show resolved Hide resolved
cups/file.c Outdated
/*
* Remove the inline comment...
*/
if ((ptr = strchr(buf, '#')) != NULL && _cups_isspace(*(ptr-1)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check how cupsFileGetConf() deals with escaped # . This way we would leave '' in the output file, which is not wanted.

cups/file.c Outdated
while(ptr > buf)
{
// Null-terminate the string after the last non-whitespace
if(!_cups_isspace(*(ptr-1)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if you used ptr[-1] instead of *(ptr-1) - it is shorter and in alignment with cupsFileGetConf().

@Ankit3002
Copy link
Author

Ankit3002 commented Apr 17, 2023

@zdohnal I made the changes as you requested . Please review them, The below is how we are taking care of inline comments now.

     if ((ptr = strchr(buf, '#')) != NULL)
     {
        while(ptr > buf)
        {
         // Null-terminate the string after the last non-whitespace, unless the '#' character is escaped by a backslash ('\')
         if(!_cups_isspace(ptr[-1]) && (ptr == buf || ptr[-1] != '\\'))
         {
           *ptr = '\0';
           break;
         }
         ptr--;
        }
     }

cups/file.c Outdated
while(ptr > buf)
{
// Null-terminate the string after the last non-whitespace, unless the '#' character is escaped by a backslash ('\')
if(!_cups_isspace(ptr[-1]) && (ptr == buf || ptr[-1] != '\\'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should deal with escaped # before we start the loop - we should enter the scope with loop only if the # is not escaped. See the cupsFileGetConf() function - you can even deal with it the similar way.

cups/file.c Outdated
*/
if(buf[0])
{
if (buf[0] == '#')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought a bit about dealing with the empty lines in the yesterday evening. We can return buf here together with buf[0] == '#', so the condition would look like:

/*
 * If we got empty line or comment, return it...
 */
if (!buf[0] || buf[0] == '#')
  return buf;

and we can remove the if(buf[0]) before that.

We just need to add a new if else if in cupsAdminSetServerSettings():

while (_cupsFileGetConfandComments(cupsd, line, sizeof(line), &value, &linenum))
{
 /*
  *  Preserve empty lines
  */
  if (!line[0])
    cupsFilePuts(temp, "\n");
  else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) &&

This should do the trick - WDYT? I guess you might show something similar in the past, but I didn't get it in the past, sorry for that :D .

Copy link
Member

@zdohnal zdohnal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed the code from code style POV - tabs weren't used on places where they should be and the indentation is shifted since the second loop.

Would you mind looking into it?

cups/file.c Outdated

char * /* O - Line read or @code NULL@ on end of file or error */
_cupsFileGetConfAndComments(cups_file_t *fp, /* I - CUPS file */
char *buf, /* O - String buffer */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According DEVELOPING.md file every 8 spaces have to be a tab - please reflect that in the new code. I'll mark every place where there is a problem.

cups/file.c Outdated
_cupsFileGetConfAndComments(cups_file_t *fp, /* I - CUPS file */
char *buf, /* O - String buffer */
size_t buflen, /* I - Size of string buffer */
char **value, /* O - Pointer to value */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use tab instead of every 8 spaces here.

cups/file.c Show resolved Hide resolved
cups/file.c Outdated
Comment on lines 383 to 392
while(ptr > buf)
{
// Null-terminate the string after the last non-whitespace, unless the '#' character is escaped by a backslash ('\')
if(!_cups_isspace(ptr[-1]) && (ptr == buf || ptr[-1] != '\\'))
{
*ptr = '\0';
break;
}
ptr--;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use tab instead of every 8 spaces here.

cups/file.c Outdated
Comment on lines 378 to 393
/*
* Remove the inline comment...
*/
if ((ptr = strchr(buf, '#')) != NULL)
{
while(ptr > buf)
{
// Null-terminate the string after the last non-whitespace, unless the '#' character is escaped by a backslash ('\')
if(!_cups_isspace(ptr[-1]) && (ptr == buf || ptr[-1] != '\\'))
{
*ptr = '\0';
break;
}
ptr--;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation - every line (except for line with opening multiblock comment /*) is indented by even number of whitespaces - (2 spaces -> 4 spaces -> 6 spaces -> 1 tab -> 1 tab and 2 spaces etc). The initial indentation here is 5, which is odd number.

cups/file.c Outdated
Comment on lines 395 to 460
/*
* Strip leading whitespace...
*/

for (ptr = buf; _cups_isspace(*ptr); ptr ++);

if (ptr > buf)
_cups_strcpy(buf, ptr);

/*
* Return the comment if any...
*/
if(buf[0])
{
if (buf[0] == '#')
return buf;

/*
* Otherwise grab any value and return...
*/

for (ptr = buf; *ptr; ptr ++)
if (_cups_isspace(*ptr))
break;

if (*ptr)
{
/*
* Have a value, skip any other spaces...
*/

while (_cups_isspace(*ptr))
*ptr++ = '\0';

if (*ptr)
*value = ptr;

/*
* Strip trailing whitespace and > for lines that begin with <...
*/

ptr += strlen(ptr) - 1;

if (buf[0] == '<' && *ptr == '>')
*ptr-- = '\0';
else if (buf[0] == '<' && *ptr != '>')
{
/*
* Syntax error...
*/

*value = NULL;
return (buf);
}

while (ptr > *value && _cups_isspace(*ptr))
*ptr-- = '\0';
}

/*
* Return the line...
*/

return (buf);

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation is incorrect till this part - incorrect number of whitespaces and no tabs were used.

@Ankit3002
Copy link
Author

@zdohnal I made the changes as you requested. Please review them.

@Ankit3002
Copy link
Author

@zdohnal I made the changes as you requested. Please review them.

@zdohnal Any Update on this ?

Copy link
Member

@zdohnal zdohnal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

good thinking about possibility of having more # on one line! IMO it would be great if that could be handled by a function, so we can call it recursively there. Would you mind looking into it?
There are other code style issues, please look into them as well.

Thank you in advance!

I'm going to vacation for next two weeks and I'll return on 15th May, so I won't be available for reviews till I return, so see you in two weeks!

cups/file.c Outdated
* Remove the backslash and continue searching for unescaped '#'...
*/
_cups_strcpy(ptr-1, ptr);
ptr = strchr(ptr+1, '#');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking here! Could you rework the functionality (recursively checking for #, because it can indicate forbidden inline comment or escaped #) into a static local function, which can be called recursively? So we can just do once:

if ((ptr = strchr(buf, '#')) != NULL)
  cups_handle_hash(ptr, buf);

this way you don't have to check for escaped # in the loop again, and the while loop can be in else scope, so we spare one conditional check.

There are code style issues as well (ptr-1 -> ptr - 1 , the comments are shifted by one space - look into other code in the file to see how they should look).

if (ptr > buf)
_cups_strcpy(buf, ptr);

/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change the comment here - now we don't return only comment, but in case of empty line as well.

cups/file.c Outdated Show resolved Hide resolved
@zdohnal
Copy link
Member

zdohnal commented May 31, 2023

Hi @Ankit3002 ,

have you got time to look into the PR?

@zdohnal zdohnal added this to the v2.4.x milestone May 31, 2023
@Ankit3002
Copy link
Author

Hi @Ankit3002 ,

have you got time to look into the PR?

Yes, I will push the changes today.

@Ankit3002
Copy link
Author

@zdohnal Please review the changes that I made ...

@Ankit3002
Copy link
Author

@zdohnal Please review the changes that I made ...

@zdohnal Any Update on this ?

@michaelrsweet michaelrsweet modified the milestones: v2.4.x, v2.5 Apr 2, 2024
@michaelrsweet
Copy link
Member

Definitely not for 2.4.x, maybe for 2.5.

@zdohnal Will leave this review process to you since you've been looking at this code more than me lately...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants